/* This file is part of node-sword-interface.

   Copyright (C) 2019 - 2026 Tobias Klein <contact@tklein.info>

   node-sword-interface 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.

   node-sword-interface 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with node-sword-interface. See the file COPYING.
   If not, see <http://www.gnu.org/licenses/>. */

#ifndef _TEXT_PROCESSOR
#define _TEXT_PROCESSOR

#include "common_defs.hpp"

namespace sword {
    class SWModule;
};

class ModuleStore;
class ModuleHelper;
class StrongsEntry;

class TextProcessor
{
public:
    TextProcessor(ModuleStore& moduleStore, ModuleHelper& moduleHelper);
    virtual ~TextProcessor() {}

    void enableMarkup() { this->_markupEnabled = true; }
    void disableMarkup() { this->_markupEnabled = false; }

    void enableStrongsWithNbsp() { this->_strongsWithNbspEnabled = true; }

    std::vector<Verse> getBibleText(std::string moduleName);
    Verse getReferenceText(std::string moduleName, std::string reference);
    std::vector<Verse> getBookText(std::string moduleName, std::string bookCode, int startVerseNumber=-1, int verseCount=-1);
    std::vector<Verse> getChapterText(std::string moduleName, std::string bookCode, int chapter);
    std::vector<Verse> getVersesFromReferences(std::string moduleName, std::vector<std::string>& references);
    std::vector<std::string> getReferencesFromReferenceRange(std::string referenceRange);
    std::string getCurrentVerseText(sword::SWModule* module, bool hasStrongs, bool hasInconsistentClosingEndDivs=false, bool forceNoMarkup=false);
    std::string getBookIntroduction(std::string moduleName, std::string bookCode);

    StrongsEntry* getStrongsEntry(std::string key);

    void processImageUrls(std::string& text, const std::string& moduleFileUrl);
    void processImageUrls(std::string& text, sword::SWModule* module);

    bool moduleHasStrongsZeroPrefixes(sword::SWModule* module);
    bool moduleHasStrongsPaddedZeroPrefixes(sword::SWModule* module);
    std::string padStrongsNumber(const std::string strongsNumber);
    bool isModuleReadable(sword::SWModule* module, std::string key="John 1:1");

    std::string mapVerseReference(std::string sourceOsisRef, std::string sourceModuleName, std::string targetModuleName, bool allowRange = false);

private:
    std::vector<Verse> getText(std::string moduleName,
                               std::string key,
                               QueryLimit queryLimit=QueryLimit::none,
                               int startVerseNr=-1,
                               int verseCount=-1);

    std::string getCurrentChapterHeading(sword::SWModule* module, const std::string& moduleFileUrl, bool hasThMLVariants);
    std::string getCurrentVerseText(sword::SWModule* module, bool hasStrongs, bool hasInconsistentClosingEndDivs, bool forceNoMarkup, const std::string& moduleFileUrl, bool hasThMLVariants);
    std::string getFilteredText(const std::string& text, int chapter, int verseNr, bool hasStrongs, bool hasInconsistentClosingEndDivs, const std::string& moduleFileUrl, bool hasThMLVariants);
    std::string getFileUrl(const std::string& nativePath);
    std::string replaceSpacesInStrongs(const std::string& text);
    unsigned int findAndReplaceAll(std::string & data, std::string toSearch, std::string replaceStr);

    // String-based replacements for regex operations (performance optimization)
    void removeElementsByPrefixSuffix(std::string& data, const std::string& prefix, const std::string& suffix);
    void replaceMilestoneLineElements(std::string& data);
    void removeMilestoneElements(std::string& data);
    void removeSegStartElements(std::string& data);
    void removeDivSectionElements(std::string& data);
    void expandSelfClosingElements(std::string& data);
    void normalizeVariantClasses(std::string& data);
    void removePbElementsWithSpace(std::string& data);

    std::string getBookFromReference(std::string reference);
    std::vector<std::string> getBookListFromReferences(std::vector<std::string>& references);

    ModuleStore& _moduleStore;
    ModuleHelper& _moduleHelper;
    bool _markupEnabled;
    bool _rawMarkupEnabled;
    bool _strongsWithNbspEnabled;
};

#endif // _TEXT_PROCESSOR