/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
 *            altcombobox.cc
 *
 *  Tue Nov 25 08:18:10 CET 2008
 *  Copyright 2008 Bent Bisballe Nyeng
 *  deva@aasimon.org
 ****************************************************************************/

/*
 *  This file is part of Pracro.
 *
 *  Pracro is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  Pracro is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Pracro; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 */
#include "altcombobox.h"

#include <QFrame>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QComboBox>

#include "common.h"
#include "multilist.h"
#include "macrowindow.h"

#include "debug.h"

AltComboBox::AltComboBox(QDomNode &node, MacroWindow *macrowindow)
  : Widget(node, macrowindow)
{
  frame = new QFrame();
  widget = frame;

  hideChildren = true;

  innerwidget = NULL;

  setCommonAttributes(frame, node);
  setCommonLayout(frame, node);
  
  combobox = new ComboBox(node, macrowindow);
  frame->layout()->addWidget(combobox->qwidget());
  combobox->qwidget()->show();

  altframerepl = new QFrame();
  QHBoxLayout *l = new QHBoxLayout();
  altframerepl->setLayout(l);
  l->addStretch();
  altframe = new QFrame();
  frame->layout()->addWidget(altframe);

  QVector< Widget* > widgets;

  QString iwname;

  QDomNodeList items = node.childNodes();
  for(int i = 0; i < items.count(); i++) {
    QDomElement item = items.at(i).toElement();

    if(item.tagName() == "altitem") {
      
      if(item.hasAttribute("value")) {
        altvalue = item.attribute("value");
      } else {
        ERROR(altcombobos, "altitem tag is missing the value attribute, "
              "in altcombobox!\n");
      }

      if(item.hasAttribute("innerwidget")) {
        iwname = item.attribute("innerwidget");
      } else {
        ERROR(altcombobox, "altitem tag is missing the innerwidget attribute, "
               "in altcombobox!\n");
      }

      if(item.hasAttribute("layout")) {
        if(item.attribute("layout") == "hbox") {
          QHBoxLayout *layout = new QHBoxLayout();
          altframe->setLayout(layout);
        } else if(item.attribute("layout") == "vbox") {
          QVBoxLayout *layout = new QVBoxLayout();
          altframe->setLayout(layout);      
        } else { // Illigal layout choosen.
          QVBoxLayout *layout = new QVBoxLayout();
          altframe->setLayout(layout);
        }
      } else {
        QHBoxLayout *layout = new QHBoxLayout();
        altframe->setLayout(layout);
      }

      addChildren(item, altframe->layout());

    }

  }

  innerwidget = findWidget(iwname, true);

  if(innerwidget == NULL) {
    ERROR(altcombobox, "Inner Widget %s not found (in altcombobox)!\n",
           iwname.toStdString().c_str());
  }

  // To detect if the altvalue has been selected:
  connect(combobox->qwidget(), SIGNAL(currentIndexChanged(int)),
          this, SLOT(onValueChange(int)));
  connect(combobox->qwidget(), SIGNAL(editTextChanged(const QString&)),
          this, SLOT(onValueChange(const QString&)));

  // To react to changes in any of the children:
  connect(combobox, SIGNAL(wasChanged()), this, SLOT(onChildChange()));
  if(innerwidget)
    connect(innerwidget, SIGNAL(wasChanged()), this, SLOT(onChildChange()));

  if(frame->layout()) frame->layout()->setContentsMargins(0,0,0,0);
  if(altframe->layout()) altframe->layout()->setContentsMargins(0,0,0,0);

  frame->show(); // Force altframe to get resized to its real size.
  altframerepl->setFixedHeight(altframe->height());
}

AltComboBox::~AltComboBox()
{
  // delete frame;
}

bool AltComboBox::preValid()
{
  if(!combobox->valid()) return false;

  if(innerwidget && combobox->value() == altvalue) {
    if(!innerwidget->valid()) return false;
  }

  return true;
}

QString AltComboBox::value()
{
  if(combobox->value() == altvalue) {
    if(innerwidget) return innerwidget->value();
    else return "";
  } else {
    return combobox->value();
  }
}

void AltComboBox::setValue(QString value, QString source)
{
  // No need for this, it will be enitted by the children.
  // if(isUserSource(source)) emit wasChanged();

  QComboBox *cmb = (QComboBox*)combobox->qwidget();
  if(cmb->findData(value) != -1) {

    combobox->setValue(value, source);

  } else {
    combobox->setValue(altvalue);

    if(innerwidget) {
      innerwidget->setValue(value, source);
    }
  }

  //  setInitialValue(value);
}

void AltComboBox::onValueChange(int index)
{
  QComboBox *cmb = (QComboBox*)combobox->qwidget();

  DEBUG(alcombobox, "Value changed: %s altvalue: %s\n",
        cmb->itemData(index).toString().toStdString().c_str(),
        altvalue.toStdString().c_str());

  if(cmb->itemData(index).toString() == altvalue) {

    altframerepl->setVisible(false);
    frame->layout()->removeWidget(altframerepl);

    frame->layout()->addWidget(altframe);
    altframe->setVisible(true);

  } else {

    altframe->setVisible(false);
    frame->layout()->removeWidget(altframe);

    frame->layout()->addWidget(altframerepl);
    altframerepl->setVisible(true);

  }

  emit eventOnChange(true);
}

void AltComboBox::onValueChange(const QString &text)
{
  QComboBox *cmb = (QComboBox*)combobox->qwidget();
  onValueChange(cmb->findText(text));
}

void AltComboBox::onChildChange()
{
  emit eventOnChange(true);
  emit wasChanged();
}

bool AltComboBox::setKeyboardFocus()
{
  if(combobox->value() == altvalue) {
    if(innerwidget) return innerwidget->setKeyboardFocus();
  }

  combobox->setKeyboardFocus();
  return true;
}

void AltComboBox::setWdgValid(bool valid)
{
  DEBUG(altcombobox, "Set valid(%s)", valid?"true":"false");

  QPalette palette;

  if(valid) {
    // valid string
    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
  } else {
    // invalid string
    palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
  }

  frame->setPalette(palette);
  combobox->qwidget()->setPalette(palette);
  //  if(innerwidget) innerwidget->setWdgValid(valid);
}