/*
    libodsstream is a library to read and write ODS documents as streams
    Copyright (C) 2013  Olivier Langella <Olivier.Langella@moulon.inra.fr>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    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 Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "saxhandlercontentxml.h"
#include <QDebug>

SaxHandlerContentXml::SaxHandlerContentXml(OdsDocReader & ods_reader) : _ods_reader(ods_reader)
{
    qDebug() << "SaxHandlerContentXml::SaxHandlerContentXml begin ";

}

SaxHandlerContentXml::~SaxHandlerContentXml()
{

}


bool
SaxHandlerContentXml::startElement(
    const QString &namespaceURI,
    const QString &localName,
    const QString &qName,
    const QXmlAttributes &attributes)
{

    qDebug() << "SaxHandlerContentXml::startElement "<< qName;
    _tag_stack.push_back(qName);
    bool is_ok = true;

    //startElement_rawdata
    if (qName == "table:table")
    {
        //  is_ok = startElement_rawdata(attributes);
        is_ok = start_element_table(attributes);
    } else if (qName == "table:table-row")
    {
        is_ok = start_element_table_row(attributes);
    }
    else if (qName == "table:table-cell")
    {
        is_ok = start_element_table_cell(attributes);
    }

    _currentText.clear();
    return is_ok;
}


bool
SaxHandlerContentXml::endElement(
    const QString &namespaceURI,
    const QString &localName,
    const QString &qName)
{
    bool is_ok = true;
    // endElement_peptide_list
    if (qName == "table:table")
    {
        is_ok = end_element_table();
    }
    // endElement_isotope_label
    else if (qName == "table:table-row")
    {
        is_ok = end_element_table_row();
    }
    else if (qName == "text:p")
    {
        is_ok = end_element_p();
    } else if (qName == "table:table-cell")
    {
        is_ok = end_element_table_cell();
    }

    _currentText.clear();
    _tag_stack.pop_back();

    return is_ok;
}


bool SaxHandlerContentXml::start_element_table_row(const QXmlAttributes &attributes) const {

    _ods_reader.startLine();
    return true;
}

bool SaxHandlerContentXml::end_element_table_row() const {

    _ods_reader.endLine();
    return true;
}


bool SaxHandlerContentXml::start_element_table(const QXmlAttributes &attributes) const {
    QString spread_sheet_name = attributes.value("table:name");
    if (spread_sheet_name.isEmpty())
    {
        //_errorStr = QObject::tr("spread_sheet_name is empty.");
        //return false;
    }
    _ods_reader.startSheet(spread_sheet_name);
    return true;
}


bool
SaxHandlerContentXml::start_element_p(const QXmlAttributes &attributes) {
    _is_in_paragraph = true;
}


bool
SaxHandlerContentXml::end_element_p() {
    _current_cell.setValueString(_currentText);
}

bool SaxHandlerContentXml::end_element_table() const {

    _ods_reader.endSheet();
    return true;
}


bool SaxHandlerContentXml::start_element_table_cell(const QXmlAttributes &attributes) {
    _is_in_paragraph = false;


    _number_columns_repeated = 1;
    _current_cell.setOfficeValueType(attributes.value("office:value-type"));


    // table:number-columns-repeated="2"
    // <table:table-cell table:number-columns-repeated="2"
    // office:value-type="string"><text:p>N.A.</text:p></table:table-cell>

    if (!attributes.value("table:number-columns-repeated").isEmpty()) {
        _number_columns_repeated = attributes.value("table:number-columns-repeated").toUInt();
        // System.out.println("coucou " + numberColumnsRepeated);
    }

    if (!_current_cell.getOfficeValueType().isEmpty()) {

        QString dateStr = attributes.value("office:date-value");
        if (!dateStr.isEmpty()) {
            //qDebug() << "dateStr " << dateStr;
            QDateTime date(QDateTime::fromString(dateStr,Qt::ISODate));
            // date.fromString(dateStr,Qt::ISODate);
            //qDebug() << " date.fromString " << date.toString(Qt::ISODate);
            _current_cell.setDateValue(date);
        }


        if (_current_cell.getOfficeValueType()=="float") {
            /*
             * writer.writeAttribute("office",
             * hashNamespaceURI.get("office"), "value-type",
             * "float"); writer.writeAttribute("office",
             * hashNamespaceURI.get("office"), "value", value);
             */
            QString valueStr = attributes.value("office:value");
            if (valueStr.isEmpty()) {
                _errorStr = QObject::tr("office:value is null");
                return false;
            }
            _current_cell.setValueDouble(valueStr.toDouble());
        }
        else if (_current_cell.getOfficeValueType()=="boolean") {
            //office:boolean-value="false" calcext:value-type="boolean" office:value-type="boolean"
            QString valueStr = attributes.value("office:boolean-value");
            _current_cell.setValueBoolean(false);
            if (valueStr.isEmpty()) {
                _current_cell.setValueBoolean(false);
            }
            else if (valueStr == "true") {
                _current_cell.setValueBoolean(true);
            }
        }
    }
    return true;
}


bool SaxHandlerContentXml::end_element_table_cell() {

    while (_number_columns_repeated > 0) {
        _ods_reader.setInsideCell(_current_cell);
        _number_columns_repeated--;
    }
    return true;
}



bool
SaxHandlerContentXml::characters(const QString &str)
{
    _currentText += str;
    return true;
}

bool
SaxHandlerContentXml::fatalError(const QXmlParseException &exception)
{
    _errorStr =
        QObject::tr("Parse error at line %1, column %2:\n"
                    "%3") .arg(exception.lineNumber()).arg(exception.columnNumber()).arg(exception.message());
    return false;
}

QString
SaxHandlerContentXml::errorString() const
{
    return _errorStr;
}

bool
SaxHandlerContentXml::endDocument()
{
    return true;
}
