/***************************************************************************
                          tokenprovider.h  -  description
                             -------------------
    begin                : Fre Sep 19 2003
    copyright            : (C) 2003 by Dominik Seichter
    email                : domseichter@web.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef TOKENPROVIDER_H
#define TOKENPROVIDER_H

#ifdef HAVE_CONFIG_H
#include <config.h>
#else
// enable JAVASCRIPT interpreter
#define USE_JAVASCRIPT
// use KJS instead of 
#define NO_KJS_EMBED
#endif

#include <tqstring.h>
#include <tqregexp.h>
#include <time.h>

#include "documentitem.h"

namespace TDEABC {
    class Addressee;
};

class tToken {
    public:
        tToken() {};
        
        tToken( const TQString & t, const TQString & d, bool a = false )
        {
            token = t;
            description = d;
	    appendix = a;
        }
    
        void operator=( const tToken & rhs )
        {
            token = rhs.token;
            description = rhs.description;
	    appendix = rhs.appendix;
        }
        
        TQString token;
        TQString description;
	bool appendix;
};

struct tCategories {
    int category;
    TQValueList<tToken> tokens;
};


#ifndef NO_KJS_EMBED
namespace KJSEmbed {
    class KJSEmbedPart;
}
#else
namespace KJS {
    class Interpreter;
}
#endif // NO_KJS_EMBED

class TQPaintDevice;

/** This class handles the replacement of tokens like [date] or [article_no].
  *
  *@author Dominik Seichter
  */
class TokenProvider {
    public: 
        enum ECategories { CAT_DATABASE, CAT_LABEL, CAT_CUSTOM, CAT_DATE, CAT_ADDRESS };

        TokenProvider( TQPaintDevice* paintdevice );
        virtual ~TokenProvider();

	static bool hasJavaScript();

        static TQValueList<tCategories>* getTokens();
        
        /**
         * Get a caption which can be displayed to the user from 
         * a ECategory enum.
         *
         * @param e the category which should be used
         *
         * @returns a translated caption which can be displayed to the user
         */
        static const TQString captionForCategory( ECategories e ) {
            return s_captions[e];
        }

        inline void updateDone() { m_update = false; }
        inline virtual bool update() {
            return m_update && m_contains_update;
        }

        inline void setIndex( unsigned int index ) { m_index = index; m_update = true; }
        inline void setPage( unsigned int page ) { m_page = page; m_update = true; }
        inline void setArticleNo( const TQString & t ) { article_no = t; m_update = true; }
        inline void setBarcodeNo( const TQString & t ) { barcode_no = t; m_update = true; }
        inline void setCustomerNo( const TQString & t ) { customer_no = t; m_update = true; }
        inline void setEncodingTypeName( const TQString & t ) { encoding_type_name = t; m_update = true; }
        inline void setGroup( const TQString & t ) { group = t; m_update = true; }
        inline void setLabelName( const TQString & t ) { label_name = t; m_update = true; }
        inline void setCol( unsigned int c ) { col = c; m_update = true; }
        inline void setRow( unsigned int r ) { row = r; m_update = true; }
        inline void setSerial( const TQString &t, unsigned int inc ) { m_serial = t; m_increment = inc; m_update = true; m_contains_update = true;}
        inline void setAddressee( TDEABC::Addressee* pAddressee ) { m_address = pAddressee; }

        inline int index() const { return m_index; }
        inline unsigned int page() const { return m_page; }
        inline const TQString & articleNo() const { return article_no; }        
        inline const TQString & barcodeNo() const { return barcode_no; }
        inline const TQString & serial() const { return m_serial; }

        inline void setPaintDevice( TQPaintDevice* paint ) { m_printer = paint; }
        inline TQPaintDevice* paintDevice() const { return m_printer; }

        /**
	 * parse the given java script code and return its result
	 * @returns    either the result of the javascript code
	 *             or an error message
	 * @p script   javascript code to execute
	 */
	TQString jsParse( const TQString & script );

        /**
	 * parse the given java script code and return its result
	 * @returns    true or false
	 * @p script   javascript code to execute
	 */
	bool jsParseToBool( const TQString & script );

        /**
          * parse the given text for tokens and return a
          * string with all tokens replaced correctly.
          * @param text TQString look in this text for tokens to replace
          */
        TQString parse( const TQString & text );


        /**
         * set @p list as DocumentItemList which is used for @see listUserVars
         */
        inline void setCurrentDocumentItems( const DocumentItemList & list );

	/**
	  * parses all DocumentItems in @p list and returns a stringlist
	  * containing all user defined variables in these DocumentItems.
	  * A user defined variable is something like [$MyVar1]. Variable
	  * names are case insensitive.
	  */
	TQStringList listUserVars();
	  

        inline void setUserVars( const TQMap<TQString,TQString> & data );

    private:
        static void init();
        
        const TQString createSerial();
	
	TQString escapeText( const TQString & t );
	TQString unescapeText( const TQString & t );

	/** A helper function called from parse
	  * which returns the value for every known 
	  * token @p text.
          */
	TQString process( const TQString & text );

	/** A helper function called from parse
	  * which returns the value for every known 
	  * token @p t.
          */
	TQString processAddresses( const TQString & t );

        /** a helper function needed by listUserVars.
	  * which adds all user defined variables to 
	  * m_findUserVars.
	  */
	TQString processUserVars( const TQString & t );

        void findBrackets( TQString & text, TQString (TokenProvider::*parserfunction)( const TQString & ) );

        /**
          * run a SQL Query and return it result
          * @param query TQString the SQL command to execute
          */
        TQString query( const TQString & query );

        unsigned int m_index;
        unsigned int m_page;
        unsigned int m_increment;

        DocumentItemList m_document_items;

	TQMap<TQString,TQString> m_uservardata;

        TQString article_no;
        TQString barcode_no;
        TQString customer_no;
        TQString encoding_type_name;
        TQString group;
        TQString label_name;
        TQString m_serial;
        unsigned int row;
        unsigned int col;

        bool m_update;
        bool m_contains_update;
        TQPaintDevice* m_printer;
	TQRegExp date_reg_exp ;

        TDEABC::Addressee* m_address;

	TQStringList* m_findUserVarsList;
        static TQValueList<tCategories> s_categories;
        static TQMap<ECategories, TQString> s_captions;

#ifdef NO_KJS_EMBED
	static KJS::Interpreter* s_interpreter;
#else	
	static KJSEmbed::KJSEmbedPart* s_interpreter;
#endif // NO_KJS_EMBED
};

inline void TokenProvider::setCurrentDocumentItems( const DocumentItemList & list )
{
    m_document_items = list;
}

inline void TokenProvider::setUserVars( const TQMap<TQString,TQString> & data )
{
    m_uservardata = data;
}

#endif
