/***************************************************************************

    source::worx xtree
    Copyright © 2024 c.holzheuer
    christoph.holzheuer@gmail.com

    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) any later version.

***************************************************************************/



//#include <cmath>
#include <xqitemtype.h>

#include <QDateTime>
#include <QDebug>

XQItemTypeMap XQItemType::s_ItemTypeMap;


///
/// XQItemType
/// 


XQItemType::XQItemType()
{

}

XQItemType::XQItemType( const XQItemType& other)
{
  _renderStyle   = other._renderStyle;
  _editorType    = other._editorType;
  _itemFlags     = other._itemFlags;
  _unitType      = other._unitType;
  _contentFormat = other._contentFormat;
  // wem gehören die dann? leck?
  _fixedChoices  = other._fixedChoices;
  _typeIcon      = other._typeIcon;
}

XQItemType::~XQItemType()
{

}


/*
XQItemType::XQItemType( RenderStyle aRenderStyle, EditorType aEditorType, Qt::ItemFlags aItemFlags, UnitType aUnitType, const QString& aContentFormat )
  : renderStyle{aRenderStyle},
    editorType{aEditorType},
    itemFlags{aItemFlags},
    unitType{aUnitType},
    contentFormat{aContentFormat}
{
  itemtypeKey = makeItemTypeKey(renderStyle,editorType,itemFlags,unitType,contentFormat);
};
*/

///
/// create attributes for from factory
///

void XQItemType::setAttribute(XQItem::RenderStyle renderStyle )
{
  _renderStyle = renderStyle;
}

void XQItemType::setAttribute(XQItem::EditorType editorType )
{
  _editorType = editorType;
}

void XQItemType::setAttribute(Qt::ItemFlags  itemFlags )
{
  _itemFlags = itemFlags;
}

void XQItemType::setAttribute(XQItem::UnitType unitType)
{
  _unitType = unitType;
}

void XQItemType::setAttribute(const QString& contentFormat)
{
  _contentFormat = contentFormat;
}

void XQItemType::setAttribute(QStandardItemModel *fixedChoices)
{
  _fixedChoices = fixedChoices;
}

void XQItemType::setAttribute(const QIcon& typeIcon )
{
  _typeIcon = typeIcon;
}


///
/// data() access for property sytem
///

XQItem::RenderStyle XQItemType::renderStyle() const
{
  return _renderStyle;
}


XQItem::EditorType XQItemType::editorType() const
{
  return _editorType;
}



XQItem::UnitType XQItemType::unitType() const
{
  return _unitType;
}

const QString& XQItemType::contentFormat() const
{
  return _contentFormat;
}


QStandardItemModel* XQItemType::fixedChoices() const
{
  return _fixedChoices;
}



QString XQItemType::unitTypeStr() const
{
  return XQItem::fetchUnitTypeStr( _unitType );
}


QString XQItemType::formatToSI( const QString& valueTxt ) const
{
  /*
  if( valueTxt.isEmpty() )
    return valueTxt;

  if( XQItem::ISODate == _unitType )
  {
    // format iso date
    QDateTime dateTime = QDateTime::fromString(valueTxt, Qt::ISODate);
    // fixme! make this configurable!
    QString format = "dd.MM.yyyy HH:mm:ss"; // You can customize this format
    // Format the QDateTime object into a human-readable string
    return dateTime.toString(format);
  }

  QLocale sysLocale = QLocale::system();
  sysLocale.setNumberOptions(sysLocale.numberOptions() | QLocale::OmitGroupSeparator);

  double dVal =  sysLocale.toDouble(valueTxt);
  QString strVal, strPrefix;

  int exp = (int)::log10f(dVal);
  exp = (exp/3)*3;

  double nVal = dVal;
  if( !s_PrefixExponentMap.key(exp).isEmpty()  )
    nVal /= ::pow( 10,exp);
  strVal =  sysLocale.toString(nVal, 'f', 2);
  strPrefix =  s_PrefixExponentMap.key(exp);
  //qDebug() << " convert: " << dVal << " : " << valueTxt << ": " << strVal  << ":" << exp  << " : " << strPrefix << ": " << nVal;

  return QString("%1 %2%3").arg( strVal, strPrefix, unitTypeStr() );
  */
  return "fitze!";
}


QString XQItemType::unFormatFromSI(const QString& formText ) const
{
  /*
  QString input = formText.simplified();
  // #1: strip numeric part
  if( input.isEmpty() )
    return input;

  int idx = 0;
  for( auto c : input )
  {
    if( c.isNumber() || c.toLower() == 'e' || c == '.' ||  c == ',' ||c == '-' || c == '+' )
      idx++;
    else
      break;
  }

  if(!idx)
    return QString("0");

  QString numPart = formText.left(idx);
  QString unitPart;
  //if(idx + 1 < formText.size() )
  unitPart = formText.right(idx - 1).simplified();

  QLocale sysLocale = QLocale::system();
  double dVal =  sysLocale.toDouble(numPart);
  if( unitPart.size() > 0 )
  {
    QString prefix = QString(unitPart[0]);
    if( s_PrefixExponentMap.contains(prefix) )
      dVal *= std::pow( 10.0, s_PrefixExponentMap[prefix] );
  }

  sysLocale.setNumberOptions(sysLocale.numberOptions() | QLocale::OmitGroupSeparator);
  QString result = sysLocale.toString(dVal, 'f', 2);

  //qDebug() << " convert: " << numPart << " : " << unitPart << " : " << dVal << " : " << result;

  return result;
  */
  return "fitze!";
}

///
/// --- statics --------------------------------------------------------------------------
///

QString XQItemType::makeItemTypeKey()
{
  return makeItemTypeKey(
    _renderStyle,
    _editorType,
    _itemFlags,
    _unitType,
    _contentFormat,
    _fixedChoices,
    _typeIcon
    );
}

QString XQItemType::makeItemTypeKey(
  XQItem::RenderStyle aRenderStyle,
  XQItem::EditorType aEditorType,
  Qt::ItemFlags aItemFlags,
  XQItem::UnitType aUnitType,
  const QString& aContentFormat,
  QStandardItemModel* aFixedChoices,
  const QIcon aIcon
  )
{
  auto combinedHash = [](const QStandardItemModel* model)
  {
    const quint32 prime = 0x9e3779b1;   // große Zufallszahl
    quint32 seed = 0;
    for (int row = 0; row < model->rowCount(); ++row) {
      const QString text = model->item(row)->text();
      quint32 h = qHash(text);
      // Verschmelzung nach Boost-Hash-Combine:
      seed ^= h + prime + (seed << 6) + (seed >> 2);
    }
    return QString::number(seed);
  };

  return QString("%1:%2:%3:%4:%5:%7:%8").arg(
    XQItem::fetchRenderStyleStr(aRenderStyle),
    XQItem::fetchEditorTypeStr(aEditorType),
    QString::number( aItemFlags.toInt() ),
    XQItem::fetchUnitTypeStr(aUnitType),
    aContentFormat,
    combinedHash(aFixedChoices),
    aIcon.name()
  );
}

/*
void XQItemType::setItemType( XQItem* item, RenderStyle renderStyle, UnitType unitType )
{
  XQItemType* itemType = XQItemType::makeItemType( renderStyle, unitType );
  item->setItemType( itemType );
}
*/





