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

#ifndef DJ_PIXEL_DATA_H
#define DJ_PIXEL_DATA_H
#include <djPixel.h>

namespace dj {

// Pixel data information.
//
class PixelDataInfo {
public:

  PixelDataInfo() {}
  PixelDataInfo(const Vec2i & size, const Pixel &);
  virtual ~PixelDataInfo() {}
  
  // Set.
  //
  virtual void set(const Vec2i & size, const Pixel &);
  virtual void size(const Vec2i &);
  virtual void pixel(const Pixel &);
  virtual void format(PIXEL_FORMAT);
  virtual void type(PIXEL_TYPE);

  // Get.
  //
  virtual const Vec2i & size() const { return _size; }
  virtual int width() const { return _size.x(); }
  virtual int height() const { return _size.y(); }
  virtual const Pixel & pixel() const { return _pixel; }
  virtual PIXEL_FORMAT format() const { return _pixel.format(); }
  virtual PIXEL_TYPE type() const { return _pixel.type(); }
  
protected:

  Vec2i _size;
  Pixel _pixel;
};

// Pixel data.
//
class PixelData : public PixelDataInfo {
public:

  PixelData();
  PixelData(const PixelData &);
  PixelData(const PixelDataInfo &);
  PixelData(const Vec2i & size, const Pixel &);
  virtual ~PixelData();
  
  // Set.
  //
  virtual PixelData & operator = (const PixelData &);
  virtual void set(const Vec2i & size, const Pixel &);
  virtual void zero();
  
  // Get.
  //
  virtual const Vec2i & size() const { return PixelDataInfo::size(); }
  virtual const Pixel & pixel() const { return PixelDataInfo::pixel(); }
  virtual PIXEL_FORMAT format() const { return PixelDataInfo::format(); }
  virtual PIXEL_TYPE type() const { return PixelDataInfo::type(); }
  
  // Data.
  //
  uint8_t * data() { return _data; }
  uint8_t * data(const Vec2i &);
  uint8_t * data(int x, int y);
  const uint8_t * data() const { return _data; }
  const uint8_t * data(const Vec2i &) const;
  const uint8_t * data(int x, int y) const;

private:

  void size(const Vec2i &) {}
  void pixel(const Pixel &) {}
  void format(PIXEL_FORMAT) {}
  void type(PIXEL_TYPE) {}
  
  virtual void del();

  void init();
  uint8_t * _data;
  int _pixelSize, _imageSize;
};

// Functions.
//
int pixelSize(const PixelDataInfo &);
int scanlineSize(const PixelDataInfo &);
int planeSize(const PixelDataInfo &);
int imageSize(const PixelDataInfo &);

void pixelCopy(
  const PixelData &, PixelData *,
  const Vec2i & position = Vec2i()
);

// Debugging.
//
Dbg & operator << (Dbg &, const PixelData &);

}

#endif
