/*------------------------------------------------------------------------------
 src/lib/djWidget/tabWidget.cxx

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

//#define DJ_DBG
#include "djTabWidget.h"
#include <djScrollWidget.h>
#include <FL/fl_draw.H>
#include <FL/Fl.H>

namespace dj {

class _TabWidget : public Widget {
public:
  _TabWidget(const Str & name, WidgetBase *);
  virtual ~_TabWidget();
  void name(const Str &);
private:
  Str _name;
  char * _nameAscii;
  WidgetBase * _widget;
};

_TabWidget::_TabWidget(const Str & name, WidgetBase * widget) :
  _name(name), _nameAscii(0),
  _widget(widget)
{
  labelfont(dj::font());
  labelsize(dj::fontSize());
  _nameAscii = toAscii(_name);
  Fl_Widget::label(_nameAscii);
  ScrollWidget * scrollWidget = new ScrollWidget;
  scrollWidget->box(FL_THIN_DOWN_FRAME);
  
  VLayout * layout = new VLayout(this);
  layout->add(scrollWidget);
  layout->stretch(scrollWidget);
  if (_widget) scrollWidget->layout()->add(_widget);
}

_TabWidget::~_TabWidget()
{
  if (_nameAscii) delete [] _nameAscii;
}

void _TabWidget::name(const Str & in)
{
  if (in == _name) return;
  
  _name = in;
  
  if (_nameAscii) delete [] _nameAscii;
  _nameAscii = toAscii(_name);
  Fl_Widget::label(_nameAscii);
}

TabWidget::TabWidget() :
  Fl_Tabs(0, 0, 0, 0)
{
  DJ_DBG_FNC("dj::TabWidget::TabWidget");
  
  end();
  
  StackLayout * layout = new StackLayout(this);
  layout->margin(0);
  
  callback(widgetCallback, this);
}

bool TabWidget::tab(int in)
{
  if (in < 0 || in >= _tabList.size()) return false;
  
  value(dynamic_cast<Fl_Widget *>(_tabList[in]));
  return true;
}
  
int TabWidget::tab() const
{
  // XXX FLTK forgot their const.
  //
  TabWidget * that = const_cast<TabWidget *>(this);
  
  return dj::find(_tabList, dynamic_cast<WidgetBase *>(that->value()));
}

void TabWidget::tabAdd(const Str & name, WidgetBase * in)
{
  DJ_DBG_FNC("dj::TabWidget::tabAdd");
  DJ_DBG_PRN("name = " << name);
  
  _TabWidget * widget = new _TabWidget(name, in);
  _tabList.add(widget);
  layout()->add(widget);
  //tab(_tabList.size() - 1);
}
  
bool TabWidget::tabName(const Str & name, int tab)
{
  if (tab < 0 || tab >= _tabList.size()) return false;
  
  DJ_DBG_FNC("dj::TabWidget::tabName");
  DJ_DBG_PRN("name = " << name);
  DJ_DBG_PRN("tab = " << tab);
  
  static_cast<_TabWidget *>(_tabList[tab])->name(name);
  redraw();
  
  return true;
}

bool TabWidget::tabDel(int in)
{
  if (in < 0 || in >= _tabList.size()) return false;
  
  DJ_DBG_FNC("dj::TabWidget::tabDel");
  DJ_DBG_PRN("in = " << in);
  
  _tabList.del(in);
  layout()->del(in);
  
  return true;
}

void TabWidget::tabDel()
{
  while (_tabList.size()) tabDel(0);
}

const Vec2i TabWidget::sizeHint() const
{
  return tabHint() + layout()->sizeHint();
}

const Vec2i TabWidget::tabHint() const
{
  return
    Vec2i(0, labelsize()) + layoutWidgetMargin() * 2 +
    Vec2i(Fl::box_dx(box()) * 2, Fl::box_dy(box()) * 3);
}

void TabWidget::resize(int x, int y, int w, int h)
{
  Fl_Widget::resize(x, y, w, h);
  LayoutItem::resize(x, y, w, h);
  layout()->resize(
    x + Fl::box_dx(box()), y + tabHint().y(),
    w - Fl::box_dx(box()) * 2, h - tabHint().y() 
  );
}

int TabWidget::visible() const { return Fl_Tabs::visible(); }

void TabWidget::draw()
{
  if (_tabList.size()) {
    fl_color(FL_BACKGROUND2_COLOR);
    fl_rectf(x(), y(), w(), tabHint().y());
  }
  
  Fl_Tabs::draw();
}
  
int TabWidget::handle(int in)
{
  switch (in) {
  
    case FL_KEYBOARD:
      switch (Fl::event_key()) {
      
        // XXX Disable arrow-key navigation.
        //
        case FL_Left:
        case FL_Right:
        case FL_Up:
        case FL_Down: return 0;
      }
      break;
      
  }
  return Fl_Tabs::handle(in);
}

void TabWidget::widgetCallback()
{
  _sig.emit(tab());
}

}
