/***************************************************************************
    begin                : Fri Aug 1 2003
    copyright            : (C) 2003 by Jeroen Wijnhout
    email                : Jeroen.Wijnhout@kdemail.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 KILEPROJECT_H
#define KILEPROJECT_H

#include <tqobject.h>
#include <tqptrlist.h>
#include <tqregexp.h>

#include "kiledebug.h"
#include <kurl.h>

class TQString;
class TQStringList;
class KSimpleConfig;
namespace KileDocument { class Info; class TextInfo; class Extensions; }

/**
 * KileProjectItem
 **/
class KileProject;
class KileProjectItemList;
class KileProjectItem : public TQObject
{
	Q_OBJECT
  TQ_OBJECT

public:
	KileProjectItem(KileProject *project = 0, const KURL &url = KURL(), int type = Source);
	~KileProjectItem() { KILE_DEBUG() << "DELETING PROJITEM " << m_path << endl;}

	bool operator==(const KileProjectItem& item) { return m_url  == item.url();}

	enum Type { ProjectFile = 0, Source, Package, Image, Other /* should be the last item*/ };

	int type() const { return m_type; }
	void setType(int type) { m_type = type; }

	bool archive() const { return m_archive; }
	void setArchive(bool ar) { m_archive = ar; }

	void setInfo(KileDocument::TextInfo * docinfo);
	KileDocument::TextInfo* getInfo() { return m_docinfo; }

	KileProject* project() const { return m_project;}

	/**
	 * @returns absolute URL of this item
	 **/
	const KURL&	url() const { return m_url; }

	/**
	 * @returns path of this item relative to the project file
	 **/
	const TQString& path() const { return m_path; }

	bool isOpen() const { return m_bOpen; }
	void setOpenState(bool state) { m_bOpen = state; }

	const TQString& encoding() const { return m_encoding;}
	void setEncoding(const TQString& encoding) {m_encoding = encoding;}

	const TQString& highlight() { return m_highlight;}
	void setHighlight(const TQString& highlight) {m_highlight = highlight;}

	uint lineNumber() { return m_nLine; }
	void setLineNumber(uint l) { m_nLine = l; }

	uint columnNumber() { return m_nColumn; }
	void setColumnNumber(uint l) { m_nColumn = l; }

	int order() const { return m_order; }
	void setOrder(int i);

	//project tree functions
	void setParent(KileProjectItem * item);

protected:
	void setChild(KileProjectItem *item) { m_child = item; }
	void setSibling(KileProjectItem *item) { m_sibling = item; }

public:
	KileProjectItem* parent() const { return m_parent; }
	KileProjectItem* firstChild() const { return m_child;}
	KileProjectItem* sibling() const { return m_sibling; }

	void allChildren(TQPtrList<KileProjectItem> *) const;

	void print(int level);

public slots:
	/**
	 * @warning Does nothing if "url" is empty !
	 **/ 
	void changeURL(const KURL &url);
	void changePath(const TQString& path) { m_path = path;}

private slots:
	void slotChangeURL(KileDocument::Info* info, const KURL& url);

signals:
	void urlChanged(KileProjectItem*);

private:
	KileProject		*m_project;
	KURL			m_url;
	TQString			m_path;
	TQString			m_encoding;
	TQString			m_highlight;
	bool			m_bOpen, m_archive;
	int			m_type;
	KileDocument::TextInfo	*m_docinfo;
	KileProjectItem		*m_parent, *m_child, *m_sibling;
	uint			m_nLine, m_nColumn;
	int			m_order;
};

class  KileProjectItemList : public TQPtrList<KileProjectItem>
{
public:
	KileProjectItemList() { setAutoDelete(true); }
	~KileProjectItemList() { KILE_DEBUG() << "DELETING KILEPROJECTITEMLIST" << endl;}
};

/**
 * KileProject
 **/
class KileProject : public TQObject
{
	Q_OBJECT
  TQ_OBJECT

public:
	KileProject(const TQString& name, const KURL& url, KileDocument::Extensions *extensions);
	KileProject(const KURL& url, KileDocument::Extensions *extensions);

	~KileProject();

	void setName(const TQString & name) { m_name = name; emit (nameChanged(name));}
	const TQString& name() const { return m_name; }

	void setMasterDocument(const TQString & master);
	const TQString& masterDocument() const { return m_masterDocument; }

	void setExtensions(KileProjectItem::Type type, const TQString & ext);
	const TQString & extensions(KileProjectItem::Type type) { return m_extensions[type-1]; }

	void setQuickBuildConfig(const TQString & cfg) { m_quickBuildConfig = cfg; }
	const TQString & quickBuildConfig() { return m_quickBuildConfig; }

    void setLastDocument(const KURL &url);
    const KURL & lastDocument() const { return m_lastDocument; }

	void setMakeIndexOptions(const TQString & opt) { m_makeIndexOptions = opt; }
	const TQString & makeIndexOptions() { return m_makeIndexOptions; }
	void readMakeIndexOptions();
	void setUseMakeIndexOptions(bool use) { m_useMakeIndexOptions = use; }
	void writeUseMakeIndexOptions();
	bool useMakeIndexOptions() { return m_useMakeIndexOptions; }

	const KURL& url() const { return m_projecturl; }
	void setURL(const KURL & url ) { m_projecturl = url; }
	const KURL& baseURL() const { return m_baseurl; }

	KileProjectItem* item(const KURL &);
	KileProjectItem* item(const KileDocument::Info *info);
	KileProjectItemList* items() { return &m_projectitems; }

	KSimpleConfig *config() { return m_config; }

	bool contains(const KURL&);
	bool contains(const KileDocument::Info *info);
	KileProjectItem *rootItem(KileProjectItem *) const;
	const TQPtrList<KileProjectItem>* rootItems() const {return &m_rootItems;}
	bool isInvalid(){ return m_invalid;}
	TQString archiveFileList() const;

signals:
	void nameChanged(const TQString &);
	void masterDocumentChanged(const TQString &);
	void projectTreeChanged(const KileProject *);

public slots:
	bool load();
	bool save();

	void add(KileProjectItem*);
	void remove(const KileProjectItem*);

	void itemRenamed(KileProjectItem*);

	void buildProjectTree(); // moved to slots by tbraun

	//debugging
	void dump();

signals:
	void loadFile(const KURL &url , const TQString & encoding);

private:
	void init(const TQString& name, const KURL& url, KileDocument::Extensions *extensions);
	TQString	findRelativePath(const KURL&);
	void setType(KileProjectItem *item);
  	TQString addBaseURL(const TQString &path);
  	TQString removeBaseURL(const TQString &path);
	void writeConfigEntry(const TQString &key,const TQString &standardExt,KileProjectItem::Type type);

private:
	TQString		m_name, m_quickBuildConfig, m_kileversion, m_kileprversion;
	KURL		m_projecturl, m_baseurl, m_lastDocument;
	bool		m_invalid;
	TQPtrList<KileProjectItem> m_rootItems;
	KileProjectItemList	m_projectitems;

	TQString		m_extensions[3];
	TQRegExp		m_reExtensions[3];

	TQString		m_masterDocument, m_makeIndexOptions;
	bool			m_useMakeIndexOptions;

	KSimpleConfig	*m_config;
	KileDocument::Extensions *m_extmanager;
};

#endif
