/*
    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);
    }
  //<office:annotation
  else if(qName == "office:annotation")
    {
      is_ok = start_element_office_annotation(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 == "text:a")
    {
      is_ok = end_element_a();
    }
  else if(qName == "table:table-cell")
    {
      is_ok = end_element_table_cell();
    }
  //<office:annotation
  else if(qName == "office:annotation")
    {
      is_ok = end_element_office_annotation();
    }

  _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
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  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);
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  return true;
}


bool
SaxHandlerContentXml::end_element_p()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  if(_is_annotation)
    return true;
  if(_current_cell._string_value.isEmpty())
    {
      _current_cell._string_value.append(_currentText);
    }
  else
    {
      _current_cell._string_value.append("\n").append(_currentText);
    }
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  return true;
}

bool
SaxHandlerContentXml::end_element_a()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  if(_is_annotation)
    return true;
  _current_cell._string_value.append(_currentText);
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  return true;
}

bool
SaxHandlerContentXml::end_element_table() const
{

  _ods_reader.endSheet();
  return true;
}


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

  _number_columns_repeated = 1;
  _current_cell.setOfficeValueType(attributes.value("office:value-type"));
  if(_current_cell.getOfficeValueType().isEmpty())
    {
      _current_cell.setOfficeValueType(attributes.value("calcext: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;
}

bool
SaxHandlerContentXml::start_element_office_annotation(
  const QXmlAttributes &attributes)
{
  _is_annotation = true;
  return true;
}

bool
SaxHandlerContentXml::end_element_office_annotation()
{
  _is_annotation = false;
  return true;
}
