/** 
 *  Yudit Unicode Editor Source File
 *
 *  GNU Copyright (C) 1997-2023  Gaspar Sinai <gaspar@yudit.org>  
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License, version 2,
 *  dated June 1991. See file COPYYING for details.
 *
 *  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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
#ifndef SSyntaxMarker_h
#define SSyntaxMarker_h

#include "stoolkit/STextData.h"
#include "stoolkit/SBinVector.h"
#include "stoolkit/SBinHashtable.h"
#include "stoolkit/SVector.h"
#include "stoolkit/SLineTracker.h"
#include "stoolkit/syntax/SMatcher.h"
#include "stoolkit/SBinHashtable.h"

// The first 0xFFFF mask bytes are real syntax
// the 0xFFFF0000 mask bytes are shadow syntax
// the upper ones are free
#define SGC_BEGIN_MARK 0x10000

class SSyntaxMarker : public SMatcherIterator, public SMatcherAction
{
public:
  // lines is the syntax markup line
  // textdata is the matching text
  // around is from where sync happens
  SSyntaxMarker (SSyntaxData& syntaxLines, const SUnicodeData& dataLines, 
     const STextIndex& around);

  virtual ~SSyntaxMarker ();
  /* must be called at the end to get minModified and maxModified */

  // This only knows about positions that were read via getNextCharacter()
  STextIndex position2Index (unsigned int position);
  int getCharAt (const STextIndex& in) const;
  int getSyntaxAt (const STextIndex& in) const;
  bool setSyntaxAt (const STextIndex& in, int syn);
  STextIndex getCurrentIndex () const
    { return STextIndex (currentIndex); }

  // you need to enclose applyAction statements with these,
  // to get minModified and maxModified.
  void beginActionBlock ();
  void endActionBlock ();

  STextIndex               minModified;
  STextIndex               maxModified;


private:
  /* SMatcherIterator */
  virtual int  getNextCharacter ();
  /* SMatcherAction */
  virtual void applyAction (const SString& name,
    unsigned int markFrom, unsigned int  markTill);

  bool decrement (STextIndex* in);
  bool increment (STextIndex* in);
  unsigned int getLineSize  (unsigned int lineno) const;
  bool isEOD (const STextIndex& idx) const;
  
  SSyntaxData&             syntaxLines;
  const SUnicodeData&      dataLines;

  /* for SMatcherIterator */
  STextIndex               startIndex;
  STextIndex               currentIndex;
  bool                     isStarted;

  /* for matcherMarkCurrentPosition */
  SBinVector<unsigned int> lineSizes;
  SBinHashtable<int>       actionMap;

};

#endif /* SSyntaxMarket_h */
