//#define DJ_DBG
#include "dpx.h"
#include <djOgl.h>
#include <FL/Fl.H>

DpxLoad::DpxLoad()
{}

bool DpxLoad::open(const Str & in)
{
  if (! _f.open(in, FileIo::READ)) return false;
  
  char magic [] = "    ";
  if (! _f.get(magic, 4)) return false;
  if (0 == memCompare(magic, "SDPX", 4)) _f.endian(endian() != MSB);
  else if (0 == memCompare(magic, "XPDS", 4)) _f.endian(endian() != LSB);
  uint32_t imageOffset;
  if (! _f.getU32(&imageOffset)) return false;
  
  if (! _f.seek(768, FileIo::SET)) return false;
  uint16_t orient;
  uint16_t elemSize;
  uint32_t size [2];
  if (! _f.getU16(&orient)) return false;
  if (! _f.getU16(&elemSize)) return false;
  if (! _f.getU32(size, 2)) return false;
  _size.set(size[0], size[1]);
  
  if (! _f.seek(imageOffset, FileIo::SET)) return false;
  
  return true;
}

ImageWidget::ImageWidget() :
  Fl_Gl_Window(0, 0, 0, 0),
  _data(0)
{}

void ImageWidget::set(const uint8_t * in, const Vec2i & size)
{
  _data = in;
  _size = size;
}

void ImageWidget::resize(int x, int y, int w, int h)
{
  Fl_Gl_Window::resize(x, y, w, h);
  LayoutItem::resize(x, y, w, h);
}

int ImageWidget::visible() const { return Fl_Gl_Window::visible(); }

//static uint8_t _tmp [2048 * 1556 * 4];

void ImageWidget::draw()
{
  // Setup.
  //
  if (! valid()) {
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    
    glViewport(0, 0, w(), h());
    oglOrtho(w(), h());
    glClearColor(1.0, 0.0, 0.0, 0.0);
  }
  
  glClear(GL_COLOR_BUFFER_BIT);
  //glColor3f(1, 1, 1);
  glRasterPos2i(0, 0);
  //glPixelZoom(0, 0);
  //glBitmap(0, 0, 0, 0, 0, 0, 0);
  //glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
  glDrawPixels(
    _size.x(), _size.y(),
    GL_RGBA, GL_UNSIGNED_INT_10_10_10_2_EXT,
    //GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT,
    //GL_RGBA, GL_UNSIGNED_BYTE,
    _data
  );
}

myApp::myApp(int & argc, char ** argv) :
  App("dpx", argc, argv),
  _frame(0),
  _timerCount(0)
{
  for (int i = 1; i < argc; ++i)
    _input += argv[i];
  
  _window = new Window;
  _widget = new ImageWidget;
  VLayout * layout = new VLayout(_window);
  layout->margin(0);
  layout->add(_widget);
  
  _window->size(Vec2i(1200, 800));
  _window->show();
  
  _timer.start();
  Fl::add_idle(timerCallback, this);
  //timerCallback();
  
  valid(true);
}

void myApp::timerCallback()
{
  DJ_DBG_FNC("myApp::timerCallback");
  
  if (! _load.open(_input[_frame])) return;
  _widget->set(_load.data(), _load.size());
  _widget->redraw();
  
  ++_frame;
  if (_frame >= _input.size()) _frame = 0;
  
  _timer.check();
  ++_timerCount;
  print(Str("fps = %1").arg(_timerCount / _timer.seconds()));
  if (_timer.seconds() >= 1.0) {
    _timer.start();
    _timerCount = 0;
  }
}

int main(int argc, char ** argv)
{
  DJ_DBG_LOG();
  return myApp(argc, argv).exec();
}
