/*------------------------------------------------------------------------------
 src/bin/djview/imageOpTool.cxx

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

//#define DJ_DBG
#include "imageOpTool.h"
#include "app.h"
#include <djImageOpStack.h>
#include <djButtonWidget.h>
#include <djTabWidget.h>
#include <djMenuWidget.h>
#include <djImageOpStackWidget.h>

namespace djview {

ImageOpTool::ImageOpTool() :
  DialogBase("Image Operation Tool"),
  _menuItems(0),
  _callbacks(true)
{
  // Widgets.
  //
  color(FL_BACKGROUND2_COLOR);
  _widget = new ImageOpStackWidget;
  _widget->set(&djviewApp->imageOpStack());
  _menuItems = new MenuItems;
  _menubar = new MenubarWidget;
  Widget * dialogFrameWidget = new Widget;
  dialogFrameWidget->box(FL_THIN_UP_BOX);
  PushButtonWidget * closeWidget = new PushButtonWidget("Clos&e");
  
  // Layout.
  //
  VLayout * windowLayout = new VLayout(this);
  windowLayout->spacing(0);
  windowLayout->margin(0);
  windowLayout->add(_menubar);
  windowLayout->add(_widget);
  windowLayout->stretch(_widget);
  windowLayout->add(dialogFrameWidget);
  HLayout * dialogFrameLayout = new HLayout(dialogFrameWidget);
  dialogFrameLayout->stretchAdd();
  dialogFrameLayout->add(closeWidget);
  
  // Initialize.
  //
  menuUpdate();
  
  // Callbacks.
  //
  _widget->updateSig().set(this, updateCallback);
  _widget->stackActiveSig().set(this, stackActiveCallback);
  _widget->stackUpdateSig().set(this, stackUpdateCallback);  
  closeWidget->sig().set(this, closeCallback);
}

ImageOpTool::~ImageOpTool()
{
  die();
  if (_menuItems) delete _menuItems;
}

void ImageOpTool::die()
{
  inputDialogDel(this, stackNameCallback);
}

void ImageOpTool::stackActive(int in)
{
  _widget->stackActive(in);
}

int ImageOpTool::stackActive() const
{
  return _widget->stackActive();
}

void ImageOpTool::stackActiveCallback(int in)
{
  if (! _callbacks) return;
  menuUpdate();
}

void ImageOpTool::stackActiveCallback()
{
  if (! _callbacks) return;
  _widget->stackActive(dj::find(_stackMenuId, _menubar->value()));
}

void ImageOpTool::updateCallback(bool)
{
  if (! _callbacks) return;
  _updateSig.emit(true);
  menuUpdate();
}

void ImageOpTool::stackUpdateCallback(int in)
{
  if (! _callbacks) return;
  _stackUpdateSig.emit(in);
}

void ImageOpTool::stackNewCallback()
{
  if (! _callbacks) return;
  _widget->stackNew();
}

void ImageOpTool::stackCopyCallback()
{
  if (! _callbacks) return;
  _widget->stackCopy(_widget->stackActive());
}

void ImageOpTool::stackDelCallback()
{
  if (! _callbacks) return;
  _widget->stackDel(_widget->stackActive());
}

void ImageOpTool::stackNameCallback(const Str & in)
{
  if (! _callbacks) return;
  _widget->stackName(in, _widget->stackActive());
}

void ImageOpTool::stackNameCallback()
{
  if (! _callbacks) return;
  const int stack = _widget->stackActive();
  if (-1 == stack) return;
  inputDialog(
    "Stack name:", djviewApp->imageOpStack().stackName(stack),
    this, stackNameCallback
  );
}

void ImageOpTool::stackLeftCallback()
{
  if (! _callbacks) return;
  _widget->stackLeft(_widget->stackActive());
}

void ImageOpTool::stackRightCallback()
{
  if (! _callbacks) return;
  _widget->stackRight(_widget->stackActive());
}

void ImageOpTool::opNewCallback()
{
  if (! _callbacks) return;
  _widget->opNew(
    djviewApp->imageOpList()[dj::find(_opMenuId, _menubar->value())],
    _widget->stackActive()
  );
}

void ImageOpTool::opCopyCallback()
{
  if (! _callbacks) return;
  _widget->opCopy(_widget->opActive(), _widget->stackActive());
}

void ImageOpTool::opDelCallback()
{
  if (! _callbacks) return;
  _widget->opDel(_widget->opActive(), _widget->stackActive());
}

void ImageOpTool::opLeftCallback()
{
  if (! _callbacks) return;
  _widget->opLeft(_widget->opActive(), _widget->stackActive());
}

void ImageOpTool::opRightCallback()
{
  if (! _callbacks) return;
  _widget->opRight(_widget->opActive(), _widget->stackActive());
}

void ImageOpTool::closeCallback(bool)
{
  if (! _callbacks) return;
  hide();
}

void ImageOpTool::widgetUpdate()
{
  _callbacks = false;
  
  _widget->widgetUpdate();
  menuUpdate();
  
  _callbacks = true;
}
  
void ImageOpTool::menuUpdate()
{
  _callbacks = false;
  
  _menuItems->del();
  
  // Stack menu.
  //
  _menuItems->add("&Stack", 0, 0, 0, FL_SUBMENU);
  
  _menuItems->add("&Stack", 0, 0, 0, FL_SUBMENU);
  _stackMenuId.del();
  for (int i = 0; i < djviewApp->imageOpStack().stackSize(); ++i)
    _stackMenuId += _menuItems->add(
      djviewApp->imageOpStack().stackName(i),
      i <= 9 ? ('1' + i) : 0, stackActiveCallback, this,
      FL_MENU_RADIO | (i == _widget->stackActive() ? FL_MENU_VALUE : 0)
    );
  _menuItems->end();
  
  _menuItems->add("&New", FL_CTRL + 'n', stackNewCallback, this);
  _menuItems->add("&Copy", FL_SHIFT + FL_CTRL + 'c', stackCopyCallback, this);
  _menuItems->add("&Rename", FL_CTRL + 'r', stackNameCallback, this);
  _menuItems->add(
    "D&elete", FL_SHIFT + FL_Delete, stackDelCallback, this,
    FL_MENU_DIVIDER
  );
  _menuItems->add("Move &Left", FL_SHIFT + '[', stackLeftCallback, this);
  _menuItems->add("Move R&ight", FL_SHIFT + ']', stackRightCallback, this);
  _menuItems->end();
  
  // Operation menu.
  //
  _menuItems->add("&Operation", 0, 0, 0, FL_SUBMENU);
  
  _menuItems->add("&New", 0, 0, 0, FL_SUBMENU);
  _opMenuId.del();
  for (ConstStrListIt it = djviewApp->imageOpList(); it.isValid(); ++it)
    _opMenuId += _menuItems->add(it(), 0, opNewCallback, this);
  _menuItems->end();
  
  _menuItems->add("&Copy", FL_CTRL + 'c', opCopyCallback, this);
  _menuItems->add(
    "D&elete", FL_Delete, opDelCallback, this,
    FL_MENU_DIVIDER
  );
  _menuItems->add("Move &Left", '[', opLeftCallback, this);
  _menuItems->add("Move &Right", ']', opRightCallback, this);
  _menuItems->end();
  
  _menuItems->end();
  _menuItems->set(_menubar);
  
  _callbacks = true;
}

}
