/***************************************************************************
    date                 : Mar 21 2007
    version              : 0.40
    copyright            : (C) 2004-2007 by Holger Danielsson
    email                : holger.danielsson@versanet.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 CODECOMPLETION_H
#define CODECOMPLETION_H

#include <tqobject.h>

#include <kate/view.h>
#include <kate/document.h>
#include <ktexteditor/codecompletioninterface.h>
#include <kconfig.h>

#include "latexcmd.h"
#include "kileabbrevview.h"

//default bullet char (a cross)
static const TQChar s_bullet_char = TQChar(0xd7);
static const TQString s_bullet = TQString(&s_bullet_char, 1);
		
/**
  *@author Holger Danielsson
  */
  
class TQTimer;

class KileInfo;

namespace KileDocument
{

//FIXME fix the way the Kate::View is passed, I'm not 100% confident m_view doesn't turn into a wild pointer
//FIXME refactor the complete class, it's pretty ugly, there are too many methods with similar names suggesting that the code could be more efficient
class CodeCompletion : public TQObject
{
	Q_OBJECT
  TQ_OBJECT

public:        
	CodeCompletion(KileInfo *ki);
	~CodeCompletion();

	enum Mode
	{
		cmLatex,
		cmEnvironment,
		cmDictionary,
		cmAbbreviation,
		cmLabel,
		cmDocumentWord
	};

	enum Type
	{
		ctNone,
		ctReference,
		ctCitation
	};

	enum KateConfigFlags
	{
		cfAutoIndent= 0x1,
		cfAutoBrackets= 0x40   
	};

	bool isActive();
	bool inProgress();
	bool autoComplete();
	CodeCompletion::Mode getMode();
	CodeCompletion::Type getType();
	CodeCompletion::Type getType(const TQString &text);

	KileInfo* info() const { return m_ki;}

	void readConfig(KConfig *config);
	void readKateConfigFlags(KConfig *config);
	void saveLocalChanges();

	void setAbbreviationListview(KileAbbrevView *listview);

public slots:
	//in these two methods we should set m_view
	void slotCharactersInserted(int, int, const TQString&);
	void editComplete(Kate::View *view, KileDocument::CodeCompletion::Mode mode);

	void slotCompletionDone(KTextEditor::CompletionEntry);
	void slotCompleteValueList();
	void slotCompletionAborted();

	void slotFilterCompletion(KTextEditor::CompletionEntry* c,TQString *s);

	// a abbreviation was modified ind the abbreviation view (add, edit or delete)
	// so the abbreviation list was must also be updated
	void slotUpdateAbbrevList(const TQString &ds, const TQString &as);

private:
	void completeWord(const TQString &text, CodeCompletion::Mode mode);
	TQString filterCompletionText(const TQString &text, const TQString &type);

	void CompletionDone(KTextEditor::CompletionEntry);
	void CompletionAborted();

	void completeFromList(const TQStringList *list,const TQString &pattern=TQString());
	void editCompleteList(KileDocument::CodeCompletion::Type type,const TQString &pattern=TQString());
	bool getCompleteWord(bool latexmode, TQString &text, KileDocument::CodeCompletion::Type &type);
	bool getReferenceWord(TQString &text);
	bool oddBackslashes(const TQString& text, int index);

	void appendNewCommands(TQValueList<KTextEditor::CompletionEntry> & list);
	void getDocumentWords(const TQString &text,TQValueList<KTextEditor::CompletionEntry> &list);

	bool completeAutoAbbreviation(const TQString &text);
	TQString getAbbreviationWord(uint row, uint col);

	CodeCompletion::Type insideReference(TQString &startpattern);

private:
	// wordlists
	TQValueList<KTextEditor::CompletionEntry> m_texlist;
	TQValueList<KTextEditor::CompletionEntry> m_dictlist;
	TQValueList<KTextEditor::CompletionEntry> m_abbrevlist;
	TQValueList<KTextEditor::CompletionEntry> m_labellist;

	KileInfo *m_ki;
	TQTimer *m_completeTimer;

	// some flags
	bool m_isenabled;
	bool m_setcursor;
	bool m_setbullets;
	bool m_closeenv;
	bool m_autocomplete;
	bool m_autocompletetext;
	bool m_autocompleteabbrev;
	bool m_citationMove;
	bool m_autoDollar;
	int  m_latexthreshold;
	int  m_textthreshold;

	// flags from Kate configuration
	bool m_autobrackets;
	bool m_autoindent;

	// state of complete: some flags
	bool m_firstconfig;
	bool m_inprogress;
	bool m_ref;
	bool m_kilecompletion;
	
	// undo text
	bool m_undo;

	// special types: ref, bib
	CodeCompletion::Type m_type;
	CodeCompletion::Type m_keylistType;

	// local abbreviation
	TQString m_localAbbrevFile;
	KileAbbrevView *m_abbrevListview;

	// internal parameter
	Kate::View *m_view;                  // View
	TQString m_text;                      // current pattern
	uint m_textlen;                      // length of current pattern
	CodeCompletion::Mode m_mode;         // completion mode
	uint m_ycursor,m_xcursor,m_xstart;   // current cursor position
	uint m_yoffset,m_xoffset;            // offset of the new cursor position

	TQString buildLatexText(const TQString &text, uint &ypos, uint &xpos);
	TQString buildEnvironmentText(const TQString &text, const TQString &type, const TQString &prefix, uint &ypos, uint &xpos);
	TQString getWhiteSpace(const TQString &s);
	TQString buildAbbreviationText(const TQString &text);
	TQString buildLabelText(const TQString &text);

	TQString parseText(const TQString &text, uint &ypos, uint &xpos, bool checkgroup);
	TQString stripParameter(const TQString &text);

	void setWordlist(const TQStringList &files,const TQString &dir, TQValueList<KTextEditor::CompletionEntry> *entrylist);
	void readWordlist(TQStringList &wordlist, const TQString &filename, bool global);
	void addCommandsToTexlist(TQStringList &wordlist);
	
	void setReferences();
	TQString getCommandList(KileDocument::CmdAttribute attrtype);
	
	void setCompletionEntries(TQValueList<KTextEditor::CompletionEntry> *list, const TQStringList &wordlist);
	void setCompletionEntriesTexmode(TQValueList<KTextEditor::CompletionEntry> *list, const TQStringList &wordlist);

	uint countEntries(const TQString &pattern, TQValueList<KTextEditor::CompletionEntry> *list, TQString *entry, TQString *type);

	void addAbbreviationEntry( const TQString &entry );
	void deleteAbbreviationEntry( const TQString &entry );
	TQString findExpansion(const TQString &abbrev);

	void autoInsertDollar();
};

}

#endif
