/**
 * \file odsstream/writer/options/odscolorscale.cpp
 * \date 10/03/2018
 * \author Olivier Langella
 * \brief structure to apply a color scale in ODS sheets
 */

/*******************************************************************************
 * Copyright (c) 2013 Olivier Langella <Olivier.Langella@u-psud.fr>.
 *
 * This file is part of the libodsstream library.
 *
 *    libodsstream is a library to read and write ODS documents as streams
 *    Copyright (C) 2013  Olivier Langella <Olivier.Langella@u-psud.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/>.
 *
 * Contributors:
 *     Olivier Langella <Olivier.Langella@u-psud.fr> - initial API and
 *implementation
 ******************************************************************************/

#include "odscolorscale.h"
#include "../../odsexception.h"
#include "../structure/metaxml.h"
#include <QDebug>
#include <QRegularExpression>


OdsColorScale::OdsColorScale(const QString &cell_start_position,
                             const QString &cell_stop_position)
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
           << cell_start_position;

  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
           << cell_stop_position;
  setCellRange(cell_start_position, cell_stop_position);
}

OdsColorScale::OdsColorScale(const OdsColorScale &other)
{
  _sheet_name          = other._sheet_name;
  _percentile_color    = other._percentile_color;
  _minimum_color       = other._minimum_color;
  _maximum_color       = other._maximum_color;
  _cell_start_position = other._cell_start_position;
  _cell_stop_position  = other._cell_stop_position;
}

OdsColorScale::~OdsColorScale()
{
}

/*
 *
</table:table-row>

    <calcext:conditional-formats>
</calcext:conditional-formats>

</table:table>
*/
bool
OdsColorScale::isInSheet(const QString &sheet_name)
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
           << sheet_name << " " << _sheet_name;
  if(_sheet_name == sheet_name)
    {
      qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " OK";
      return true;
    }
  return false;
}
void
OdsColorScale::writeConditionalFormat(QXmlStreamWriter *p_writer)
{

  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  QString sheet_name = _sheet_name;
  if(sheet_name.contains(" "))
    {
      sheet_name = QString("&apos;%1&apos;").arg(sheet_name);
    }


  //<calcext:conditional-format
  //calcext:target-range-address="Feuille1.C2:Feuille1.D4">
  p_writer->writeStartElement(MetaXml::getNamespaceURI("calcext"),
                              "conditional-format");
  p_writer->device()->write(
    QString(" calcext:target-range-address=\"%1.%2:%1.%3\" ")
      .arg(sheet_name)
      .arg(_cell_start_position)
      .arg(_cell_stop_position)
      .toUtf8());
  // p_writer->writeAttribute(MetaXml::getNamespaceURI("calcext"),
  // "target-range-address",QString("%1:%2").arg(cell_start_position).arg(cell_stop_position));

  //<calcext:color-scale>
  p_writer->writeStartElement(MetaXml::getNamespaceURI("calcext"),
                              "color-scale");
  //<calcext:color-scale-entry calcext:value="0" calcext:type="minimum"
  //calcext:color="#ff0000"/>
  p_writer->writeStartElement(MetaXml::getNamespaceURI("calcext"),
                              "color-scale-entry");
  p_writer->writeAttribute(MetaXml::getNamespaceURI("calcext"), "value", "0");
  p_writer->writeAttribute(
    MetaXml::getNamespaceURI("calcext"), "type", "minimum");
  p_writer->writeAttribute(
    MetaXml::getNamespaceURI("calcext"), "color", _minimum_color.name());
  p_writer->writeEndElement();
  //<calcext:color-scale-entry calcext:value="50" calcext:type="percentile"
  //calcext:color="#ffffff"/>
  p_writer->writeStartElement(MetaXml::getNamespaceURI("calcext"),
                              "color-scale-entry");
  p_writer->writeAttribute(MetaXml::getNamespaceURI("calcext"), "value", "50");
  p_writer->writeAttribute(
    MetaXml::getNamespaceURI("calcext"), "type", "percentile");
  p_writer->writeAttribute(
    MetaXml::getNamespaceURI("calcext"), "color", _percentile_color.name());
  p_writer->writeEndElement();
  //<calcext:color-scale-entry calcext:value="0" calcext:type="maximum"
  //calcext:color="#0000ff"/>
  p_writer->writeStartElement(MetaXml::getNamespaceURI("calcext"),
                              "color-scale-entry");
  p_writer->writeAttribute(MetaXml::getNamespaceURI("calcext"), "value", "0");
  p_writer->writeAttribute(
    MetaXml::getNamespaceURI("calcext"), "type", "maximum");
  p_writer->writeAttribute(
    MetaXml::getNamespaceURI("calcext"), "color", _maximum_color.name());
  p_writer->writeEndElement();
  //</calcext:color-scale>
  p_writer->writeEndElement();
  //</calcext:conditional-format>
  p_writer->writeEndElement();
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}


std::tuple<QString, QString>
OdsColorScale::parseCellRange(const QString &cell_position)
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  if(cell_position.isEmpty())
    {
      throw OdsException(
        QObject::tr("error parsing cell range :\n empty cell position"));
    }
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
           << cell_position;
  QRegularExpression reg_exp("^(.*)\\.([A-Z]+[0-9]+)$");
  QRegularExpressionMatch reg_exp_match = reg_exp.match(cell_position);
  if(reg_exp_match.hasMatch())
    {
      qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
               << cell_position;
      return std::make_tuple(reg_exp_match.capturedTexts().at(1),
                             reg_exp_match.capturedTexts().at(2));
    }
  else
    {
      throw OdsException(
        QObject::tr("error parsing cell range :\n cell_position %1 does not "
                    "contains pattern ^(.*).([A-Z]+[0-9]+)$")
          .arg(cell_position));
    }
}

void
OdsColorScale::setCellRange(const QString &cell_start_position,
                            const QString &cell_stop_position)
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  if(cell_start_position.isEmpty() && cell_stop_position.isEmpty())
    return; // this is not an ods doc writer
  QString sheet_name;
  std::tie(sheet_name, _cell_start_position) =
    parseCellRange(cell_start_position);
  _sheet_name = sheet_name;

  std::tie(sheet_name, _cell_stop_position) =
    parseCellRange(cell_stop_position);
  //"Feuille1.C2:Feuille1.D4"
  if(sheet_name != _sheet_name)
    {
      throw OdsException(
        QObject::tr("error in OdsColorScale::setCellRange :\n start %1 and "
                    "stop %2 are not on the same sheet")
          .arg(cell_start_position)
          .arg(cell_stop_position));
    }
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}
void
OdsColorScale::setMinimumColor(const QColor &minimum_color)
{
  _minimum_color = minimum_color;
}
void
OdsColorScale::setMaximumColor(const QColor &maximum_color)
{
  _maximum_color = maximum_color;
}
