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

#ifndef DJ_IMAGE_OP_XFORM_H
#define DJ_IMAGE_OP_XFORM_H
#include <djImageOp.h>

namespace dj {

// Image mirror operation.
//
class ImageOpMirror : public ImageOp1 {
public:

  enum MIRROR { NONE, HORIZONTAL, VERTICAL, BOTH };

  ImageOpMirror();

  const Str name() const { return "Mirror"; }
  Plugin * copy() const { return new ImageOpMirror(*this); }

  enum ATTR { ATTR_VALUE };
  const StrList attrNameList() const;
  bool attr(const Str &, const StrList &);
  const StrList attr(const Str &) const;

  const Image work(const InputList &) const;
  
  static const Image work(const Image &, MIRROR);

private:

  MIRROR _value;
};

// Image rotate operation.
//
class ImageOpRotate90 : public ImageOp1 {
public:

  enum ROTATE { ROTATE_0, ROTATE_90, ROTATE_180, ROTATE_270 };

  ImageOpRotate90();

  const Str name() const { return "Rotate 90"; }
  Plugin * copy() const { return new ImageOpRotate90(*this); }
  
  enum ATTR { ATTR_VALUE };
  const StrList attrNameList() const;
  bool attr(const Str &, const StrList &);
  const StrList attr(const Str &) const;

  const PixelDataInfo info(const InfoList &) const;
  const Image work(const InputList &) const;

  static const PixelDataInfo info(const PixelDataInfo &, ROTATE);
  static const Image work(const Image &, ROTATE);

private:

  ROTATE _value;
};

// Image scale operation.
//
// References:
//
// * Dale Schumacher, "General Filtered Image Rescaling", "Graphics Gems III".
//
class ImageOpScale : public ImageOp1 {
public:

  enum FILTER {
    AUTO, BOX, TRIANGLE, BELL, BSPLINE, LANCZOS3, CUBIC, MITCHELL
  };

  ImageOpScale();

  const Str name() const { return "Scale"; }
  Plugin * copy() const { return new ImageOpScale(*this); }
  
  enum ATTR { ATTR_SIZE, ATTR_FILTER, ATTR_EDGE };
  const StrList attrNameList() const;
  bool attr(const Str &, const StrList &);
  const StrList attr(const Str &) const;
  
  const PixelDataInfo info(const InfoList &) const;
  const Image work(const InputList &) const;

  static const PixelDataInfo info(const PixelDataInfo &, const Vec2i & size);
  static const Image work(
    const Image &,
    const Vec2i & size,
    FILTER filterX = AUTO, FILTER filterY = AUTO,
    Image::EDGE edgeX = Image::EDGE_MIRROR,
    Image::EDGE edgeY = Image::EDGE_MIRROR
  );

private:

  Vec2i _size;
  FILTER _filterX, _filterY;
  Image::EDGE _edgeX, _edgeY;
};

// Utility.
//
inline const List<ImageOp *> imageOpXformList()
{
  List<ImageOp *> out;
  out += new ImageOpMirror;
  out += new ImageOpRotate90;
  out += new ImageOpScale;
  return out;
}

// Labels.
//
inline const StrList imageOpMirrorStr()
  { return StrList() + Str("None") + Str("Horizontal") + Str("Vertical") +
    Str("Both"); }
inline const StrList imageOpMirrorAttrStr()
  { return StrList() + Str("Value"); }
inline const StrList imageOpRotate90Str()
  { return StrList() + Str("0") + Str("90") + Str("180") + Str("270"); }
inline const StrList imageOpRotate90AttrStr()
  { return StrList() + Str("Value"); }
inline const StrList imageOpScaleFilterStr()
  { return StrList() + Str("Auto") + Str("Box") + Str("Triangle") +
    Str("Bell") + Str("B-Spline") + Str("Lanczos3") + Str("Cubic") +
    Str("Mitchell"); }
inline const StrList imageOpScaleAttrStr()
  { return StrList() + Str("Size") + Str("Filter") + Str("Edge"); }

}

#endif
