/*------------------------------------------------------------------------------
 src/lib/djWidget/fileBrowserItem.cxx
 
 Copyright (c) 2004-2006 Darby Johnston.
 All rights reserved.
 Use is subject to license terms.
------------------------------------------------------------------------------*/

//#define DJ_DBG
#include "djFileBrowser.h"
#include <djImageIo.h>
#include <djImageOpXform.h>
#include <FL/Fl.H>
#include <FL/fl_draw.H>

namespace dj {

FileBrowserItem::FileBrowserItem() :
  _imageFl(0), _imageValid(false), _imageSizeValid(false)
{}

FileBrowserItem::~FileBrowserItem()
{
  if (_imageFl) delete _imageFl;
}

void FileBrowserItem::set(const FileInfo & in)
{
  _value = in;
}

static const Vec2i _imageScale(
  const Vec2i & in, bool proxyScale, int * proxy = 0
) {
  const int imageSize = max(in.x(), in.y());

  int _proxy = 0;
  double _proxyScale = imageProxyScale(_proxy);
  if (proxyScale) {
    while ((imageSize / _proxyScale) > layoutThumbnailSize())
      _proxyScale = imageProxyScale(++_proxy);
    if (proxy) *proxy = _proxy;
  }
  
  double scale = layoutThumbnailSize() / (imageSize / _proxyScale);
  return Vec2i(
    ceil(in.x() / _proxyScale * scale),
    ceil(in.y() / _proxyScale * scale)
  );
}

Fl_Image * FileBrowserItem::image(bool proxyScale) const
{
  if (_imageValid) return _imageFl;
  
  DJ_DBG_FNC("dj::FileBrowserItem::image");

  FileBrowserItem * that = const_cast<FileBrowserItem *>(this);

  ImageIoInfo info;
  ImageLoad * load = imageLoad(_value, &info);
  if (load) {
  
    fl_cursor(FL_CURSOR_WAIT);
    Fl::flush();

    //that->_imageIoPlugin = load->name();
    //that->_imageIoInfo = load->info();
    
    // Determine size.
    //
    int proxy = 0;
    that->_imageSize = _imageScale(info.size(), proxyScale, &proxy);
    that->_imageSizeValid = true;
    DJ_DBG_PRN("image size = " << _imageSize);

    // Load image.
    //
    Image image;
    load->get(&image, proxy, PIXEL_RGB, PIXEL_U8);
    DJ_DBG_PRN("image = " << *image);

    image = ImageOpMirror::work(
      ImageOpScale::work(
        image,
        _imageSize,
        ImageOpScale::BOX, ImageOpScale::BOX
      ),
      ImageOpMirror::VERTICAL
    );
      
    that->_imageFl = Fl_RGB_Image(
      image.data(), image.width(), image.height()
    ).copy();

    fl_cursor(FL_CURSOR_DEFAULT);
    
    delete load;
  }

  that->_imageValid = true;
  return _imageFl;
}

const Vec2i & FileBrowserItem::imageSize(bool proxyScale) const
{
  if (_imageSizeValid) return _imageSize;

  FileBrowserItem * that = const_cast<FileBrowserItem *>(this);

  ImageIoInfo info;
  ImageLoad * load = imageLoad(_value, &info);
  if (load) {
    that->_imageSize = _imageScale(info.size(), proxyScale);
    delete load;
  }

  that->_imageSizeValid = true;
  return _imageSize;
}

}
