/*------------------------------------------------------------------------------
 src/lib/djImage/djImageIo.h
 
 Copyright (c) 2004-2006 Darby Johnston.
 All rights reserved.
 Use is subject to license terms.
------------------------------------------------------------------------------*/

#ifndef DJ_IMAGE_IO_H
#define DJ_IMAGE_IO_H
#include <djFileInfo.h>
#include <djPlugin.h>
#include <djImage.h>

namespace dj {

// Image I/O information.
//
class ImageIoInfo : public PixelDataInfo {
public:

  ImageIoInfo();

  // Tags.
  //
  void tagList(const ImageTagList &);
  const ImageTagList & tagList() const { return _tagList; }
  
  // Time.
  //
  void time(int start, int end, double speed);
  void time(const Seq &);
  void timeStart(int);
  void timeEnd(int);
  void timeSpeed(double);
  int timeStart() const { return _timeStart; }
  int timeEnd() const { return _timeEnd; }
  double timeSpeed() const { return _timeSpeed; }
  
private:

  ImageTagList _tagList;
  int _timeStart, _timeEnd;
  double _timeSpeed;
};

// Image I/O base.
//
class ImageIo : public Plugin {
public:

  virtual ~ImageIo() = 0;
  
  // File extensions.
  //
  virtual const StrList extensionList() const { return StrList(); }
};

// Image load base.
//
class ImageLoad : public ImageIo {
public:

  virtual ~ImageLoad() = 0;
  
  // Open/close.
  //
  virtual bool open(const Str & fileName, ImageIoInfo *) = 0;
  virtual void close() {}
  
  // Get image.
  //
  virtual bool get(
    Image *,
    int proxy = 0,
    int format = -1, int type = -1,
    int frame = -1
  );
  
protected:

  virtual bool imageBegin(int frame, ImageIoInfo *) = 0;
  virtual bool imageGet(PixelData *, int proxyScale) = 0;
};

// Image save base.
//
class ImageSave : public ImageIo {
public:

  virtual ~ImageSave() = 0;
  
  // Open/close.
  //
  virtual bool open(const Str & fileName, const ImageIoInfo &) = 0;
  virtual void close() {}
  
  // Set image.
  //
  virtual bool set(const Image &, int frame = -1);

protected:

  virtual bool imageBegin(const Image &, int frame) = 0;
  virtual bool imageSet(const PixelData &) = 0;
};

// Plugin entry points.
//
typedef const List<ImageLoad *> (ImageLoadFnc)();
typedef const List<ImageSave *> (ImageSaveFnc)();

// Image I/O factories.
//
class ImageLoadFactory : public PluginFactory {
public:

  ~ImageLoadFactory();
  
  const List<ImageLoad *> & pluginList() { return _pluginList; }
  ImageLoad * pluginFind(const Str &);
  ImageLoad * pluginCopy(const Str &);
  void pluginAdd(const List<ImageLoad *> &);
  
protected:

  const Str pluginPrefix() const { return Str("djImageIo"); }
  bool init(void *);
  void del();
  
private:

  List<ImageLoad *> _pluginList;
};
class ImageSaveFactory : public PluginFactory {
public:

  ~ImageSaveFactory();
  
  const List<ImageSave *> & pluginList() { return _pluginList; }
  ImageSave * pluginFind(const Str &);
  ImageSave * pluginCopy(const Str &);
  void pluginAdd(const List<ImageSave *> &);
  
protected:

  const Str pluginPrefix() const { return Str("djImageIo"); }
  bool init(void *);
  void del();
  
private:

  List<ImageSave *> _pluginList;
};

// Global image I/O functions. By default the file extension determines which
// plugin is used.
//
ImageLoad * imageLoad(
  const Str & fileName, ImageIoInfo * = 0,
  const Str & pluginName = Str(), const PluginAttr & = PluginAttr()
);
ImageSave * imageSave(
  const Str & fileName,
  const ImageIoInfo &,
  const Str & pluginName = Str(), const PluginAttr & = PluginAttr()
);

// Global functions to set plugin attributes.
//
bool imageLoadAttr(const Str & pluginName, const Str &, const StrList &);
bool imageSaveAttr(const Str & pluginName, const Str &, const StrList &);

// Utility.
//
const StrList pluginNameList(const List<ImageLoad *> &);
const StrList pluginNameList(const List<ImageSave *> &);

// XXX Limit max proxy scale.
//
static const int imageIoProxyMax = 10;

}

#endif
