/***************************************************************************
 *   Copyright 2007-2008 Wouter Haffmans <cheetah@simply-life.net>         *
 *                                                                         *
 *   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) version 3 or any later version        *
 *   accepted by the membership of KDE e.V. (or its successor approved     *
 *   by the membership of KDE e.V.), which shall act as a proxy            *
 *   defined in Section 14 of version 3 of the license.                    *
 *                                                                         *
 *   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#include "drawingreader.h"

#include <QDomDocument>

#include <QByteArray>
#include <QDataStream>
#include <kio/netaccess.h>
#include <KFilterDev>

#include <QtDebug>

#include "graphicslinesitem.h"
#include "palettemanagerxml.h"

DrawingReader::DrawingReader()
{
    init();
}

DrawingReader::DrawingReader(KUrl url, QWidget *window)
{
    init();
    load(url, window);
}

DrawingReader::~DrawingReader()
{
}

bool DrawingReader::load(KUrl url, QWidget *window)
{
    QString tmpFile;
    bool result = m_valid = false;
    if (KIO::NetAccess::download(url, tmpFile, window)) {
        // Open file
        QIODevice *file = KFilterDev::deviceForFile(tmpFile, "application/x-gzip");

        if (file->open(QIODevice::ReadOnly)) {
            // Init stream, check header
            QByteArray data;
            while (!file->atEnd()) {
                data.append(file->readAll());
            }
            QDomDocument document;
            document.setContent(data);

            QDomElement root = document.documentElement();
            QString version = root.attribute("version", "0");


            // Version 1
            if (version == "2.0") {
                result = loadVersion1(document);
            }
            // Unknown version
            else {
                result = false;
            }
        } // if open

        delete file;
        KIO::NetAccess::removeTempFile(tmpFile);
        m_valid = result;
        return result;
    }
    return false;
}

bool DrawingReader::isValid()
{
    return m_valid;
}

int DrawingReader::fileVersion()
{
    return m_version;
}

QImage DrawingReader::backgroundImage()
{
    return m_background;
}

CanvasScene::BackgroundStyle DrawingReader::backgroundStyle()
{
    return m_backgroundStyle;
}

QString DrawingReader::paletteName()
{
    return m_paletteName;
}

Palette DrawingReader::palette()
{
    return m_palette;
}

QList<GraphicsLinesItem *> DrawingReader::lines()
{
    return m_lines;
}

void DrawingReader::setPenTemplate(QPen pen)
{
    m_penTemplate = pen;
}

void DrawingReader::init()
{
    // Set default values
    m_valid = false;
    m_version = -1;
    m_backgroundStyle = CanvasScene::center;

    // Load default palette, prevent stupidness :)
    Color white, black;
    white.color = QColor(Qt::white);
    white.border = QColor(Qt::black);
    white.background = QColor(Qt::black);
    black.color = QColor(Qt::black);
    black.border = QColor(Qt::white);
    black.background = QColor(Qt::white);

    m_palette.append(white);
    m_palette.append(black);
}

bool DrawingReader::loadVersion1(QDomDocument document)
{
    m_version = 1;
    readPaletteV1(document);
    readBackgroundV1(document);
    readLinesV1(document);
    return true;
}

void DrawingReader::readPaletteV1(QDomDocument document)
{
    QDomElement root = document.documentElement();
    QDomElement paletteRoot = root.elementsByTagName("palette").at(0).toElement();

    m_palette.clear();
    if (paletteRoot.isNull()) {
        m_paletteName.clear();
        return;
    }

    m_paletteName = paletteRoot.attribute("name", QString());

    // Read colors
    QDomNodeList colorElements = paletteRoot.elementsByTagName("color");
    for (int i = 0; i < colorElements.count(); ++i) {
        Color c = PaletteManagerXML::elementToColor(colorElements.at(i).toElement());
        m_palette.append(c);
    }
}

void DrawingReader::readBackgroundV1(QDomDocument document)
{
    QDomElement root = document.documentElement();
    QDomElement backgroundRoot = root.elementsByTagName("background").at(0).toElement();

    if (backgroundRoot.isNull()) {
        m_background = QImage();
        m_backgroundStyle = CanvasScene::center;
        return;
    }

    QString styleString = backgroundRoot.attribute("style", "center");
    m_backgroundStyle = CanvasScene::backgroundStyleFromString(styleString);

    // And the image
    QDomNodeList children = backgroundRoot.childNodes();
    QByteArray backgroundData;
    for (int i = 0; i < children.count(); ++i) {
        if (children.at(i).isCDATASection()) {
            QDomCDATASection data = children.at(i).toCDATASection();
            backgroundData = QByteArray::fromBase64(data.data().toAscii());
            break;

        }
        else if (children.at(i).isText()) {
            QDomText data = children.at(i).toText();
            backgroundData = QByteArray::fromBase64(data.data().toAscii());
            break;
        }
    }

    if (backgroundData.isNull()) {
        m_background = QImage();
    }
    m_background.loadFromData(backgroundData, "PNG");
}

void DrawingReader::readLinesV1(QDomDocument document)
{
    QDomElement root = document.documentElement();
    QDomElement linesRoot = root.elementsByTagName("lines").at(0).toElement();
    m_lines.clear();

    if (linesRoot.isNull()) {
        return;
    }

    QDomNodeList lineNodes = linesRoot.elementsByTagName("line");
    for (int i = 0; i < lineNodes.count(); ++i) {
        QDomElement lineElement = lineNodes.at(i).toElement();
        int tag = lineElement.attribute("penColor", "0").toInt();
        int penWidth = lineElement.attribute("penWidth", "0").toInt();
        int zValue = lineElement.attribute("zValue", "0").toInt();
        QStringList pointStrings = lineElement.attribute("points", QString()).split(' ', QString::SkipEmptyParts);

        // Create pen
        QPen pen = m_penTemplate;
        if (0 <= tag && tag < m_palette.size()) {
            pen.setColor(m_palette.at(tag).color);
        }
        pen.setWidth(penWidth);

        QVector<QPointF> points;
        Q_FOREACH(const QString &point, pointStrings) {
            QStringList coords = point.split(',');
            int x = coords.at(0).toInt();
            int y = coords.at(1).toInt();
            points << QPointF(x, y);
        }
        // Create line element
        GraphicsLinesItem *line = new GraphicsLinesItem();
        line->setPen(pen);
        line->setTag(tag);
        line->setPoints(points);
        line->setZValue(zValue);
        m_lines.append(line);
    }
}
