/******************************************************************************
 *      "Copyright (C) 2006, ApS s.r.o Brno, All Rights Reserved"             *
 ******************************************************************************
 *============================================================================*
 *   Version „number“    Header/source file for the project   "file name"     *
 *----------------------------------------------------------------------------*
 * VERSION   DATE    TIME  BY   CHANGE/COMMENTS                               *
 *----------------------------------------------------------------------------*
 *============================================================================*/

/////////////////////////////////////////////////////////////////////
//
//  file: dsmknittingalg.h: interface for the knitting algorithm.
//
//
//////////////////////////////////////////////////////////////////////

#ifndef _KNITTINGALG_H_INCLUDED_
#define _KNITTINGALG_H_INCLUDED_

#include "isacctypes.h"
#include "dsmutils.h"

#define KSTR_INIT_SIZE 2

//Class which implements functions for CKnittingAlg
class CKnittingString{
	
	public:
		CKnittingString() {}
		~CKnittingString() {}

		/* type that represents string */
		typedef struct tagKnittingString {
		  int nAllocated; /* amount of allocated memory for this string */
		  int nLength;   /* position of terminating zero  */
		  char* sCont;   /* pointer to allocated string - if this pointer is NULL, other members of this structure have no meaning */
		} kstr_t;

		//Init kstr_t string
		void ks_init(kstr_t *psStr);
		//alloc memory for kstr_t
		void ks_alloc(kstr_t *psStr, int pnCount);
		//free memory of kstr_t
		void ks_free(kstr_t *psStr);
		//concatenane 2 kstr_t
		void ks_cat(kstr_t *psDest, const char *psSrc);
		//move psSrc to psDest
		void ks_moveto(kstr_t *psDest, kstr_t *psSrc);	
		//debug function
		#ifdef NDEBUG
		void ks_print(kstr_t psStr);
		#endif
};

class CKnittingAlg : public CKnittingString, public CUtils{
	
	private:
		kstr_t *m_pTable; 
		UINT m_nFirstID;
		UINT m_nLastID;
		
		bool  m_bInitialized;
	
	public:
		CKnittingAlg() {}
		CKnittingAlg(const UINT nFirstID, const UINT nLastID);
		~CKnittingAlg();

		/* initializes the algorithm and nonterminals-table  */
		/*   the table is indexed from nFirstID to nLastID (including both border values) */
		void ka_init(const UINT nFirstID, const UINT nLastID);
		
		/* releases all dynamically allocated resources  */		
		void ka_close();

		/* tests whether is anything "hung" on destination nonterm.  */
		/*   if the according string is not NULL, then it raises some error because there should't  */
		/*   be anything */
		/*  - now only for testing purposes, but maybe in the future may be used for something useful */
		bool ka_beginaction(const UINT nID);

		/* and symetric function */
		bool ka_finishaction(const UINT nID);

		/* takes the string "hung" on the source nonterminal and appends it to the string that  */
		/*   is hung on destination string */
		
		/* this function does as decribed above, but if is the destination pointer to string */
		/*  NULL, it sets this pointer to the value of source string pointer and then sets the source  */
		/*  pointer to NULL */
		void ka_appendnonterm(const UINT nDestID, const UINT nSrcID);

		/* these functions append received string to the destination string */
		/*   if the dest. str. pointer is null, it allocates a new one and */
		/*   copies received string to it */
		void ka_appendterm(const UINT nDestID, const char* sTerm);

		/* same as previous, but if the last parameter is true, then this */
		/*  function also frees the received string */
		void ka_appendattr(const UINT nDestID, char* sAttr, const bool bFreeAfter);

		/* returns pointer to string that is hung on the nonter with id nID */
		/*   do not edit contents of this string */
		char* ka_getvalue(const UINT nID);

		/* deallocates string associated with selected nonterminal */
		void ka_freevalue(const UINT nID);
		
};

#endif /*#ifndef _KNITTINGALG_H_INCLUDED_*/
