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

//#define DJ_DBG
#include "djImageOpXformWidget.h"
#include <djLabelWidget.h>
#include <djGroupBoxWidget.h>
#include <djVecWidget.h>

namespace dj {

ImageOpScaleWidget::ImageOpScaleWidget() :
  _callbacks(true)
{
  GroupBoxWidget * sizeGroup = new GroupBoxWidget("Size");
  _sizeWidget = new Vec2iWidget;
  _sizeWidget->alignPolicy(LEFT, CENTER);
  GroupBoxWidget * optionsGroup = new GroupBoxWidget("Options");
  LabelWidget * filterLabel = new LabelWidget("Filter:");
  _filterWidget =
    new EnumWidget<ImageOpScale::FILTER>(imageOpScaleFilterStr());
  _filter2Widget =
    new EnumWidget<ImageOpScale::FILTER>(imageOpScaleFilterStr());
  LabelWidget * edgeLabel = new LabelWidget("Edges:");
  _edgeWidget = new EnumWidget<Image::EDGE>(imageEdgeStr());
  _edgeWidget->alignPolicy(LEFT, CENTER);
  _edge2Widget = new EnumWidget<Image::EDGE>(imageEdgeStr());
  _edge2Widget->alignPolicy(LEFT, CENTER);
  
  List<LabelWidget *> labelList;
  labelList += filterLabel;
  labelList += edgeLabel;
  filterLabel->labelGroup(labelList);
  edgeLabel->labelGroup(labelList);
  
  VLayout * layout = new VLayout(this);
  layout->add(sizeGroup);
  sizeGroup->layout()->add(_sizeWidget);
  layout->add(optionsGroup);
  HLayout * subLayout = new HLayout(optionsGroup->layout());
  subLayout->margin(0);
  subLayout->add(filterLabel);
  subLayout->add(_filterWidget);
  subLayout->add(_filter2Widget);
  subLayout = new HLayout(optionsGroup->layout());
  subLayout->margin(0);
  subLayout->add(edgeLabel);
  subLayout->add(_edgeWidget);
  subLayout->add(_edge2Widget);
  layout->stretchAdd();
  
  widgetUpdate();
  
  _sizeWidget->sig().set(this, sizeCallback);
  _filterWidget->sig().set(this, filterCallback);
  _filter2Widget->sig().set(this, filter2Callback);
  _edgeWidget->sig().set(this, edgeCallback);
  _edge2Widget->sig().set(this, edge2Callback);
}

void ImageOpScaleWidget::set(ImageOp * in)
{
  ImageOpWidget::set(in);
  widgetUpdate();
}
  
void ImageOpScaleWidget::widgetUpdate()
{
  _callbacks = false;
  
  Vec2i size;
  ImageOpScale::FILTER filter = ImageOpScale::FILTER(0),
    filter2 = ImageOpScale::FILTER(0);
  Image::EDGE edge = Image::EDGE(0), edge2 = Image::EDGE(0);
  if (_op) {
    StrList data = _op->attr(imageOpScaleAttrStr()[ImageOpScale::ATTR_SIZE]);
    inflateStr(data, &size);
    data = _op->attr(imageOpScaleAttrStr()[ImageOpScale::ATTR_FILTER]);
    inflateStr(data, &filter, imageOpScaleFilterStr());
    inflateStr(data, &filter2, imageOpScaleFilterStr());
    data = _op->attr(imageOpScaleAttrStr()[ImageOpScale::ATTR_EDGE]);
    inflateStr(data, &edge, imageEdgeStr());
    inflateStr(data, &edge2, imageEdgeStr());
  }
  _sizeWidget->set(size);
  _filterWidget->set(filter);
  _filter2Widget->set(filter2);
  _edgeWidget->set(edge);
  _edge2Widget->set(edge2);
  
  _callbacks = true;
}

void ImageOpScaleWidget::sizeCallback(const Vec2i & in)
{
  if (! _callbacks || ! _op) return;
  _op->attr(imageOpScaleAttrStr()[ImageOpScale::ATTR_SIZE], deflateStr(in));
  sig().emit(true);
  widgetUpdate();
}

void ImageOpScaleWidget::filterCallback(ImageOpScale::FILTER in)
{
  if (! _callbacks || ! _op) return;
  _op->attr(
    imageOpScaleAttrStr()[ImageOpScale::ATTR_FILTER],
    deflateStr(in, imageOpScaleFilterStr()) +
      deflateStr(_filter2Widget->get(), imageOpScaleFilterStr())
  );
  sig().emit(true);
  widgetUpdate();
}

void ImageOpScaleWidget::filter2Callback(ImageOpScale::FILTER in)
{
  if (! _callbacks || ! _op) return;
  _op->attr(
    imageOpScaleAttrStr()[ImageOpScale::ATTR_FILTER],
    deflateStr(_filterWidget->get(), imageOpScaleFilterStr()) +
      deflateStr(in, imageOpScaleFilterStr())
  );
  sig().emit(true);
  widgetUpdate();
}
  
void ImageOpScaleWidget::edgeCallback(Image::EDGE in)
{
  if (! _callbacks || ! _op) return;
  _op->attr(
    imageOpScaleAttrStr()[ImageOpScale::ATTR_EDGE],
    deflateStr(in, imageEdgeStr()) +
      deflateStr(_edge2Widget->get(), imageEdgeStr())
  );
  sig().emit(true);
  widgetUpdate();
}

void ImageOpScaleWidget::edge2Callback(Image::EDGE in)
{
  if (! _callbacks || ! _op) return;
  _op->attr(
    imageOpScaleAttrStr()[ImageOpScale::ATTR_EDGE],
    deflateStr(_edgeWidget->get(), imageEdgeStr()) +
      deflateStr(in, imageEdgeStr())
  );
  sig().emit(true);
  widgetUpdate();
}

}
