/***************************************************************************
 *   Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org>             *
 *                                                                         *
 *   This program 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.                                   *
 ***************************************************************************/
#include "xml_data_file.h"

#include <tqfile.h>
#include <tqstringlist.h>
#include <ksimpleconfig.h>
#include <klocale.h>
#include "common/global/pfile.h"

XmlDataFile::XmlDataFile(const PURL::Url &url, const TQString &name)
  : _url(url), _name(name), _document(name)
{
  TQDomElement root = _document.createElement(name);
  _document.appendChild(root);
}

bool XmlDataFile::load(TQString &error)
{
  Log::StringView sview;
  PURL::File file(_url, sview);
  if ( !file.openForRead() ) {
    error = i18n("Error opening file: %1").arg(sview.string());
    return false;
  }
  if ( !_document.setContent(file.qfile(), false, &error) ) return false;
  if ( _document.doctype().name()!=_name
       || _document.documentElement().nodeName()!=_name ) {
    error = i18n("File is not of correct type.");
    return false;
  }
  return true;
}

bool XmlDataFile::save(TQString &error) const
{
  Log::StringView sview;
  PURL::File file(_url, sview);
  bool ok = file.openForWrite();
  if (ok) {
    TQString s = _document.toString(2);
    file.appendText(s);
    ok = file.close();
  }
  if ( !ok ) error = i18n("Error saving file: %1").arg(sview.string());
  return ok;
}

TQDomElement XmlDataFile::findChildElement(TQDomElement parent, const TQString &name) const
{
  TQDomNodeList list = parent.elementsByTagName(name);
  return list.item(0).toElement();
}

TQDomElement XmlDataFile::createChildElement(TQDomElement parent, const TQString &name)
{
  TQDomNodeList list = parent.elementsByTagName(name);
  if ( list.count()==0 ) {
    TQDomElement element = _document.createElement(name);
    parent.appendChild(element);
    return element;
  }
  return list.item(0).toElement();
}

void XmlDataFile::removeChilds(TQDomNode parent) const
{
  TQDomNodeList list = parent.childNodes();
  for (uint i=0; i<list.count(); i++)
    parent.removeChild(list.item(i));
}

TQString XmlDataFile::value(const TQString &group, const TQString &key, const TQString &defValue) const
{
  TQDomElement root = _document.documentElement();
  TQDomElement groupElement = findChildElement(root, group);
  if ( groupElement.isNull() ) return defValue;
  TQDomElement element = findChildElement(groupElement, key);
  if ( element.isNull() ) return defValue;
  TQDomText text = element.firstChild().toText();
  if ( text.isNull() ) return defValue;
  return text.data();
}

void XmlDataFile::setValue(const TQString &group, const TQString &key, const TQString &value)
{
  TQDomElement root = _document.documentElement();
  TQDomElement groupElement = createChildElement(root, group);
  TQDomElement element = createChildElement(groupElement, key);
  removeChilds(element);
  TQDomText text = _document.createTextNode(value);
  element.appendChild(text);
}

TQStringList XmlDataFile::listValues(const TQString &group, const TQString &key, const TQStringList &defaultValues) const
{
  TQStringList list;
  TQDomElement root = _document.documentElement();
  TQDomElement groupElement = findChildElement(root, group);
  if ( groupElement.isNull() ) return defaultValues;
  TQDomElement element = findChildElement(groupElement, key);
  if ( element.isNull() ) return defaultValues;
  TQDomNodeList childs = element.childNodes();
  if ( childs.count()==1 ) { // legacy compatibility
    TQDomText text = element.firstChild().toText();
    if ( !text.isNull() ) return text.data();
  }
  for (uint i=0; i<childs.count(); i++) {
    TQDomText text = childs.item(i).toElement().firstChild().toText();
    if ( text.isNull() ) continue;
    list.append(text.data());
  }
  return list;
}

void XmlDataFile::appendListValue(const TQString &group, const TQString &key, const TQString &value)
{
  TQDomElement root = _document.documentElement();
  TQDomElement groupElement = createChildElement(root, group);
  TQDomElement element = createChildElement(groupElement, key);
  TQDomElement item = _document.createElement("item");
  element.appendChild(item);
  TQDomText text = _document.createTextNode(value);
  item.appendChild(text);
}

void XmlDataFile::removeListValue(const TQString &group, const TQString &key, const TQString &value)
{
  TQDomElement root = _document.documentElement();
  TQDomElement groupElement = createChildElement(root, group);
  TQDomElement element = createChildElement(groupElement, key);
  TQDomNodeList list = element.childNodes();
  for (uint i=0; i<list.count(); i++) {
    TQDomElement item = list.item(i).toElement();
    TQDomText text = item.firstChild().toText();
    if ( text.isNull() || text.data()!=value ) continue;
    element.removeChild(item);
    break;
  }
}

void XmlDataFile::clearList(const TQString &group, const TQString &key)
{
  TQDomElement root = _document.documentElement();
  TQDomElement groupElement = createChildElement(root, group);
  TQDomElement element = createChildElement(groupElement, key);
  groupElement.removeChild(element);
}

void XmlDataFile::setListValues(const TQString &group, const TQString &key, const TQStringList &values)
{
  clearList(group, key);
  for (uint i=0; i<values.count(); i++) appendListValue(group, key, values[i]);
}
