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

//#define DJ_DBG
#include "djImageOpXform.h"

namespace dj {

ImageOpMirror::ImageOpMirror() :
  _value(HORIZONTAL)
{}

const StrList ImageOpMirror::attrNameList() const
  { return imageOpMirrorAttrStr(); }

bool ImageOpMirror::attr(const Str & in, const StrList & data)
{
  StrList tmp = data;
  if (compareCase(attrNameList()[ATTR_VALUE], in)) {
    if (! inflateStr(tmp, &_value, imageOpMirrorStr())) return false;
  } else
    return false;
  return true;
}

const StrList ImageOpMirror::attr(const Str & in) const
{
  StrList out;
  if (compareCase(attrNameList()[ATTR_VALUE], in))
    out += deflateStr(_value, imageOpMirrorStr());
  return out;
}

const Image ImageOpMirror::work(const InputList & in) const
{
  return in.size() ? work(*in[0], _value) : Image();
}

const Image ImageOpMirror::work(const Image & in, MIRROR mirror)
{
  DJ_DBG_FNC("dj::ImageOpMirror::work");
  DJ_DBG_PRN("in = " << in);
  DJ_DBG_PRN("value = " << mirror);
  
  // Setup.
  //
  Image out(in.size(), in.pixel());
  out.proxy(in.proxy());
  out.tagList(in.tagList());

  // Work.
  //
  const int w = out.width(), h = out.height();
  const int pixelSize = dj::pixelSize(out);
  switch (mirror) {
  
    case NONE:
      pixelCopy(in, &out);
      break;

    case HORIZONTAL: {
      for (int y = 0; y < h; ++y) {
        const uint8_t * inP = in.data(in.width() - 1, y);
        uint8_t * outP = out.data(0, y);
        for (int x = 0; x < w; ++x, inP -= pixelSize, outP += pixelSize)
          memCopy(inP, outP, pixelSize);
      }
    } break;
    
    case VERTICAL:
      for (int y = 0; y < h; ++y)
        pixelCopy(
          in.data(0, in.height() - 1 - y), out.data(0, y),
          w, in.pixel(), out.pixel()
        );
      break;
      
    case BOTH: {
      for (int y = 0; y < h; ++y) {
        const uint8_t * inP = in.data(in.width() - 1, in.height() - 1 - y);
        uint8_t * outP = out.data(0, y);
        for (int x = 0; x < w; ++x, inP -= pixelSize, outP += pixelSize)
          memCopy(inP, outP, pixelSize);
      }
    } break;
  }
  
  return out;
}

}
