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

    source::worx xtree
    Copyright © 2024-2025 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 <xqcommand.h>
#include <xqviewmodel.h>
#include <xqtreetable.h>


//! hilfsfunktion: zeigt alle position und die zugehörigen knoten an.

void XQNodeStore::dumpList( const QString& title ) const
{
  if( !title.isEmpty() )
    qDebug() << " --- " << title;
  for( const auto& entry : *this )
    qDebug() << " -- dumpList: itemPos: " << entry.itemPos  << " nodePos: " << entry.nodePos << " id: " << ( entry.contentNode ? entry.contentNode->_id : 0 ) << " used: " << ( entry.contentNode ? entry.contentNode.use_count() : 0 );
}


//! kostruktor. übergibt command-type und die aufrufende viewModel.

XQCommand::XQCommand(CmdType cmdType, XQViewModel* viewModel )
  : _cmdType{ cmdType }, _viewModel(viewModel)
{
  
}


//! destruktor

XQCommand::~XQCommand()
{
  qDebug() << " --- command destructor: " << toString();
}



//! gibt den enum-type dieses commands zurück.

XQCommand::CmdType XQCommand::commandType() const
{
  return _cmdType;
}


//! setzt den enum-type dieses commands.

void XQCommand::setCommandType( XQCommand::CmdType cmdType )
{
  _cmdType = cmdType;
}


//! ruft 'onCommandRedo' 'meines' models auf.

void XQCommand::redo()
{
  _viewModel->onCommandRedo( *this );
}


//! ruft 'onCommandUndo' 'meines' models auf.

void XQCommand::undo()
{  
  _viewModel->onCommandUndo( *this );
}


//! gibt den urpsrungs-index dieses commands zurück.

const QModelIndex& XQCommand::originIndex() const
{
  return _originIndex;
}


//! merkt sich den ersten QModelIndex der von diesem command
//! betroffenen items. zusätzlich wird der command-text erzeugt.

void XQCommand::setOriginIndex( const QModelIndex& origin )
{
  QString cmdText("%1: %2 (%3)");
  QString name = origin.data().toString();
  QString items("%1 item%2");
  int mySize = size();
  items = items.arg(mySize).arg(mySize > 1 ? "s" : "");
  cmdText = cmdText.arg( toString(), name, items );
  _originIndex = origin;
  setText(cmdText);
}


//! erzeugt aus den 'selected indices' eine liste mit der jewiligen knotenposition,
//! der item-zeile und dem content-knoten.

void XQCommand::saveNodes( const QModelIndexList& list )
{
  clear();
  // über jede zeile
  for( auto entry : list )
  {
    // knoten holen
    const XQNodePtr& contentNode = XQItem::xqItemFromIndex( entry ).contentNode();
    // hier speichern wir den original knoten, nicht einen clone, wie im clipboard.
    // obacht: bei einem Header is der content node null
    if(contentNode)
      push_back( {entry.row(), contentNode->own_pos(), contentNode } );
  }
}


//! erzeugt einen string aus dem command-type, fürs debuggen.

QString XQCommand::toString() const
{

  static QMap<CmdType,QString> s_CmdTypeMap
  {
    { cmdTextEdit,      "cmdTextEdit" },
    { cmdInvalid,       "cmdInvalid" },
    { cmdCut,           "cmdCut" },
    { cmdPaste,         "cmdPaste" },
    { cmdPasteSelf,     "cmdPasteSelf" },
    { cmdNew,           "cmdNew" },
    { cmdUndo,          "cmdUndo" },
    { cmdRedo,          "cmdRedo" },
    { cmdCopy,          "cmdCopy" },
    { cmdMove,          "cmdMove" },
    { cmdDelete,        "cmdDelete" },
    { cmdToggleSection, "cmdToggleSection" },
    { cmdExtern,        "cmdExtern" }
  };

  if( !s_CmdTypeMap.contains( _cmdType ))
    return QString(" cmdType missmatch");
  return s_CmdTypeMap[_cmdType];

}
