// Copyright (C) 1999-2015
// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
// For conditions of distribution and use, see copyright notice in "copyright"

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

#include "frametrue.h"

FrameTrue::FrameTrue(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item)
  : FrameBase(i, c, item)
{
  colormapXM = NULL;
  colormapPM = 0;
  colormapGCXOR = 0;

  byteorder_ = 0;
  bitsperpixel_ = 0;
}

FrameTrue::~FrameTrue()
{
  if (colormapXM)
    XDestroyImage(colormapXM);

  if (colormapPM)
    Tk_FreePixmap(display, colormapPM);

  if (colormapGCXOR)
    XFreeGC(display, colormapGCXOR);
}

void FrameTrue::rotateMotion()
{
  // Rotate from src to dest
  Vector cc = Vector(options->width,options->height)/2;
  Matrix m = (Translate(-cc) * Rotate(rotation-rotateRotation) * 
	      Translate(cc)).invert();
  double* mm = m.mm();

  int& width = options->width;
  int& height = options->height;
  char* src = rotateSrcXM->data;

  int bytesPerPixel = rotateDestXM->bits_per_pixel/8;

  for (int j=0; j<height; j++) {
    // the line may be padded at the end
    char* dest = rotateDestXM->data + j*rotateDestXM->bytes_per_line;
    memset(dest,0,rotateDestXM->bytes_per_line);

    for (int i=0; i<width; i++, dest+=bytesPerPixel) {
      double x = i*mm[0] + j*mm[3] + mm[6];
      double y = i*mm[1] + j*mm[4] + mm[7];

      if (x >= 0 && x < width && y >= 0 && y < height) {
#if _MACOSX
	// I really don't understand this
	char* sptr = src + ((int)y)*rotateDestXM->bytes_per_line+
	  ((int)x)*bytesPerPixel;

	*(dest+0) = *(sptr+3);
	*(dest+1) = *(sptr+0);
	*(dest+2) = *(sptr+1);
	*(dest+3) = *(sptr+2);
#else
	memcpy(dest, src + ((int)y)*rotateDestXM->bytes_per_line +
	  ((int)x)*bytesPerPixel, bytesPerPixel);
#endif
      }
      else
	memcpy(dest, bgTrueColor_, bytesPerPixel);
    }
  }

  // XImage to Pixmap
  XPutImage(display, rotatePM, gc, rotateDestXM,
	    0, 0, 0, 0, options->width, options->height);

  // Display Pixmap
  Vector dd = Vector() * widgetToWindow;
  XCopyArea(display, rotatePM, Tk_WindowId(tkwin), rotateGCXOR, 0, 0, 
	    options->width, options->height, dd[0], dd[1]);
}
