/***************************************************************************
 *   Copyright (C) 2005 by the G System Team                               *
 *   http://www.g-system.at                                                *
 *                                                                         *
 *   Permission is hereby granted, free of charge, to any person obtaining *
 *   a copy of this software and associated documentation files (the       *
 *   "Software"), to deal in the Software without restriction, including   *
 *   without limitation the rights to use, copy, modify, merge, publish,   *
 *   distribute, sublicense, and/or sell copies of the Software, and to    *
 *   permit persons to whom the Software is furnished to do so, subject to *
 *   the following conditions:                                             *
 *                                                                         *
 *   The above copyright notice and this permission notice shall be        *
 *   included in all copies or substantial portions of the Software.       *
 *                                                                         *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
 *   OTHER DEALINGS IN THE SOFTWARE.                                       *
 ***************************************************************************/

#include "GweXmlConfigurator.h"

#include <kurlrequester.h>
#include <kfile.h>
#include <klistview.h>
#include <kpushbutton.h>
#include <kmessagebox.h>

#include <qfile.h>
#include <qvaluelist.h>

#include <GWorldEngineFactory.h>

namespace GOD
{

GListViewOptionItem::GListViewOptionItem(GWE::GweFactoryOption* option, QListView* parent)
: QListViewItem(parent,option->getOptionName(),option->getValue(),option->getDescription()),
  AssociatedOption(option)
{
  this->setRenameEnabled(1,true);  // value
  this->setRenameEnabled(2,true);  // description
}

GListViewOptionItem::GListViewOptionItem(GWE::GweFactoryOption* option, QListViewItem* parent)
: QListViewItem(parent,option->getOptionName(),option->getValue(),option->getDescription()),
  AssociatedOption(option)
{
  this->setRenameEnabled(1,true);  // value
  this->setRenameEnabled(2,true);  // description
}

GListViewOptionItem::~GListViewOptionItem()
{
}

void GListViewOptionItem::okRename(int col)
{
  QListViewItem::okRename(col);
  qDebug(QString("Option ") + AssociatedOption->getOptionName() + ", column " + QString::number(col) + " changed to " + text(col));
  if (col==1)
  {
    this->AssociatedOption->setValue(text(col));
    emit this->valueChanged(AssociatedOption,this->text(col));
  }
  else if (col==2)
  {
    this->AssociatedOption->setDescription(text(col));
    emit this->descriptionChanged(AssociatedOption,this->text(col));
  }
}

GweXmlConfigurator::GweXmlConfigurator(const QString& url, QWidget *parent, const char *name)
 : GweXmlConfiguratorBase(parent, name),
   Factory(new GWE::GWorldEngineFactory())
{
  this->UrlRequester->setMode(KFile::File);
  
  this->OptionsTree->addColumn("Option");
  this->OptionsTree->addColumn("Value");
  this->OptionsTree->addColumn("Description");
  
  this->OptionsTree->setRenameable(0,false);  // option name
  this->OptionsTree->setRenameable(1);  // value
  this->OptionsTree->setRenameable(2);  // description
  this->OptionsTree->setItemsRenameable(true);
  
  this->UrlRequester->setURL(url);
  if (!url.isEmpty())
  {
    qDebug(QString("Loading options from given file: %1").arg(url));
    if (!loadFromUrl(url))
    {
      qWarning("File could not be loaded, setting it as filename anyway and starting a fresh configuration.");
      this->updateOptionsView();
      KMessageBox::information(this,QString("The chosen configuration file %1 does not yet exist, make sure you save before closing!").arg(url));
    }
  }
  else
  {
    qDebug("No file given, starting a fresh configuration.");
    this->updateOptionsView();
  }
  
  connect(UrlRequester,SIGNAL(returnPressed(const QString&)),this,SLOT(loadFromUrl(const QString& )));
  connect(UrlRequester,SIGNAL(urlSelected(const QString&)),this,SLOT(loadFromUrl(const QString& )));
  connect(ButtonReset,SIGNAL(clicked()),this,SLOT(loadConfiguration()));
  connect(ButtonSave,SIGNAL(clicked()),this,SLOT(saveConfiguration()));
}


GweXmlConfigurator::~GweXmlConfigurator()
{
}

bool GweXmlConfigurator::loadFromUrl(const QString& url)
{
  QFile file(url);
  if (file.open(IO_ReadOnly))
  {
    qDebug(QString("file opened in read only mode: ") + url);
    QDomDocument xml;
    QString error_msg;
    int line,col;
    if (!xml.setContent(&file,&error_msg,&line,&col))
    {
      qWarning("failed to load XML data from file!");
      qWarning(QString::number(line) + ":" + QString::number(col) + ": " + error_msg);
    }
    else
    {
      Factory->getRootOption()->loadFromXml(xml.documentElement());
      qDebug("factory settings loaded from file");
    }
    file.close();
  }
  else
  {
    return false;
  }
  
  //load the config from the factory into the klistview tree
  updateOptionsView();
  return true;
}

bool GweXmlConfigurator::saveToUrl(const QString& url)
{
  QFile file(url);
  if (file.open(IO_WriteOnly))
  {
    qDebug(QString("file opened for writing: ") + url);
    QDomDocument xml;
    QDomElement root_element = xml.createElement(Factory->getRootOption()->getOptionName());
    if (root_element.isNull())
    {
      qWarning("couldn't create root element");
    }
    else
    {
      xml.appendChild(root_element);
      Factory->getRootOption()->saveToXml(root_element);
      qDebug("writing xml to file");
      file.writeBlock(xml.toString(),xml.toString().length());
    }
    file.close();
  }
  else
  {
    qWarning("failed to save the configuration");
    KMessageBox::error(this,"Failed to save configuration.\n Make sure you have write permissions.");
    return false;
  }
  return true;
}

bool GweXmlConfigurator::loadConfiguration()
{
  return this->loadFromUrl(this->UrlRequester->url());
}

bool GweXmlConfigurator::saveConfiguration()
{
  return this->saveToUrl(this->UrlRequester->url());
}

void GweXmlConfigurator::updateOptionsView()
{
  qDebug("updating options view");
  this->OptionsTree->clear();
  GWE::GweFactoryOption* option = this->Factory->getRootOption();
  if (option)
  {
    GListViewOptionItem* item = new GListViewOptionItem(option,this->OptionsTree);
    connect(item,SIGNAL(valueChanged(GWE::GweFactoryOption*, const QString& )),
            this,SLOT(updateOptionsView()));
    
    updateSubOptions(option,item);
    item->setOpen(true);
    this->OptionsTree->update();
  }
}

void GweXmlConfigurator::updateSubOptions(GWE::GweFactoryOption* option, QListViewItem* parent)
{
  qDebug(QString("updating for suboption ") + option->getOptionName());
  option->updateTree();
  QValueList<GWE::GweFactoryOption*> sub_options = option->getSubOptions();
  if (sub_options.isEmpty())
    return;
  
  QValueList<GWE::GweFactoryOption*>::iterator it;
  for (it = sub_options.begin(); it != sub_options.end(); ++it)
  {
    GListViewOptionItem* item = new GListViewOptionItem((*it),parent);
    connect(item,SIGNAL(valueChanged(GWE::GweFactoryOption*, const QString& )),
            this,SLOT(updateOptionsView()));
    updateSubOptions((*it),item);
    item->setOpen(true);
  }
}

}


syntax highlighted by Code2HTML, v. 0.9.1