#include "xmlreader.h"
#include <QDebug>
#include <QFile>
#include <QDomNodeList>

XMLReader::XMLReader(QObject *parent)
    :QObject(parent)
{
}

XMLReader::~XMLReader()
{

}


bool XMLReader::parserFile(const QString &xmlFile, QDomNode &root)
{
    QFile f(xmlFile);
    if(!f.open(QIODevice::ReadOnly)) {
        errorString = QString("Open file: %1 failed.\n%2").arg(xmlFile).arg(f.errorString());
        return false;
    }

    int errorLine, errorColumn;
    if(!xmlDoc.setContent(&f, &errorString, &errorLine, &errorColumn)) {
        errorString += QString(" Line: %1, Column: %2").arg(errorLine).arg(errorColumn);
        return false;
    }
    root = xmlDoc.firstChild();
    return true;
}

bool XMLReader::parser(const QString &xmlString)
{
    int errorLine, errorColumn;
    if(!xmlDoc.setContent(xmlString, &errorString, &errorLine, &errorColumn)) {
        errorString += QString(" Line: %1, Column: %2").arg(errorLine).arg(errorColumn);
        return false;
    }
    return true;
}

QList<QDomNode> XMLReader::findElements(const QString &name)
{

    QList<QDomNode> nodeList;
    QDomNodeList domNodeList = xmlDoc.elementsByTagName(name);
    for(int i=0; i<domNodeList.length(); i++) {
        nodeList.append(domNodeList.at(i));
    }
    return nodeList;
}

QList<QDomNode> XMLReader::findElementsByAttr(const QString &name, const Attributes &attr)
{
    QList<QDomNode> nodeList = findElements(name);
    foreach (QDomNode node, nodeList) {
        foreach (QString attrName, attr.keys()) {
            QString attrValue = attr[attrName];
            if(!checkAttributeValue(node, attrName, attrValue)) {
                nodeList.removeOne(node);
                break;
            }
        }
    }
    return nodeList;
}


QMap<QString, QList<QDomNode> > XMLReader::groupElementsByAttr(const QString &nodeName, const QString &attrName)
{
    QMap<QString, QList<QDomNode> > nodeMap;
    QList<QDomNode> nodeList = findElements(nodeName);
    foreach (QDomNode node, nodeList) {
        QString attrValue = getAttributeValue(node, attrName);
        if(nodeMap.contains(attrValue)) {
            nodeMap[attrValue].append(node);
        } else {
            QList<QDomNode> tempNodeList;
            tempNodeList.append(node);
            nodeMap[attrValue] = tempNodeList;
        }
    }
    return nodeMap;
}

Attributes XMLReader::getAttributes(const QDomNode &node)
{
    Attributes attrs;
    QDomNamedNodeMap attrNodeMap = node.attributes();
    for(int i=0; i<attrNodeMap.length(); i++) {
        QDomNode attrNode = attrNodeMap.item(i);
        if(attrNode.isAttr()) {
            attrs[attrNode.nodeName()] = attrNode.nodeValue();
        }
    }
    return attrs;
}

QString XMLReader::getAttributeValue(const QDomNode &node, const QString &attrName)
{
    QString value;
    if(!node.hasAttributes()) {
        errorString = QString("Node: %1 don't has any attrs.").arg(node.nodeName());;
    } else {
        QDomNamedNodeMap attrs = node.attributes();
        if(!attrs.contains(attrName)) {
            errorString = QString("Node: %1 don't has attr: %2.").arg(node.nodeName()).arg(attrName);
        } else {
            QDomNode attr = attrs.namedItem(attrName);
            value = attr.toAttr().value();
        }
    }
    return value;
}

bool XMLReader::checkAttributeValue(const QDomNode &node, const QString &attrName, const QString &attrValue)
{
    QString value = getAttributeValue(node, attrName);
    return (value == attrValue);
}
