//	Zinc Application Framework - Z_TREE.HPP
//	COPYRIGHT (C) 1990-1999.  All Rights Reserved.
//	Zinc Software Incorporated.  Pleasant Grove, Utah  USA

#if !defined(Z_TREE_HPP)
#define Z_TREE_HPP
#include <z_button.hpp>

// --------------------------------------------------------------------------
// ----- ZafTreeList --------------------------------------------------------
// --------------------------------------------------------------------------
#if defined(ZAF_MSWINDOWS) && defined(ZAF_WIN32)
class ZAF_EXPORT ZafTreeImageList;
#endif

class ZAF_EXPORT ZafTreeItem;

class ZAF_EXPORT ZafTreeList : public ZafWindow
{
public:
	// --- General members ---
	ZafTreeList(int left, int top, int width, int height);
	ZafTreeList(const ZafTreeList &copy);
	virtual ~ZafTreeList(void);
	// view access
	ZafTreeItem *SetViewCurrent(ZafTreeItem *item);
	int ViewCount(void);
	ZafTreeItem *ViewCurrent(void);
	ZafTreeItem *ViewFirst(void);
	ZafTreeItem *ViewLast(void);
	// depth access
	ZafWindowObject *AddDepthItem(const ZafIChar *pathName, ZafWindowObject *object);
	ZafTreeItem *DepthFirst(void);
	ZafTreeItem *DepthCurrent(void);
	ZafTreeItem *DepthLast(void);

	// --- Persistent members ---
	virtual ZafWindowObject *Duplicate(void);
#if defined(USE_ZAF_PERSISTENCE)
	ZafTreeList(const ZafIChar *name, ZafObjectPersistence &persist);
	static ZafElement *Read(const ZafIChar *name, ZafObjectPersistence &persist);
	virtual void Write(ZafObjectPersistence &persist);
#endif

	// --- Attributes ---
	// get
	bool AutoSortData(void) const;
	bool DrawLines(void) const;
	ZafTreeItem *FirstVisible(void) const;
	ZafTreeItem *LastVisible(void) const;
	// set
	virtual bool SetAutoSortData(bool autoSortData);
	virtual bool SetDrawLines(bool drawLines);
	ZafTreeItem *SetFirstVisible(ZafTreeItem *);

	// --- Window members ---
	virtual bool SetDestroyable(bool destroyable);
	virtual bool SetLocked(bool locked);
	virtual bool SetMaximized(bool maximized);
	virtual bool SetMinimized(bool minimized);
	virtual bool SetModal(bool modal);
	virtual bool SetMoveable(bool moveable);
	virtual bool SetNormalHotKeys(bool normalHotKeys);
	virtual ZafWindow *SetOwner(ZafWindow *owner);
	virtual ZafSelectionType SetSelectionType(ZafSelectionType selectionType);
	virtual bool SetSizeable(bool sizeable);
	virtual bool SetTemporary(bool temporary);

	// --- Window object members ---
	virtual ZafRegionStruct ConvertToDrawRegion(const ZafWindowObject *object,
		const ZafRegionStruct *zafRegion = ZAF_NULLP(ZafRegionStruct)) const;
	virtual ZafEventType Event(const ZafEventStruct &event);
	virtual void GetClip(ZafWindowObject *object, ZafRegionStruct &clip, ZafRegionStruct &viewPort);
	ZafLogicalEvent LogicalEvent(const ZafEventStruct &event);
	virtual ZafWindowObject *NotifyFocus(ZafWindowObject *object, bool focus);
	virtual bool SetAutomaticUpdate(bool automaticUpdate);
	virtual ZafLogicalColor SetBackgroundColor(ZafLogicalColor color, ZafLogicalColor mono = ZAF_MONO_NULL);
	virtual bool SetCopyDraggable(bool copyDraggable);
	virtual bool SetFocus(bool currentFocus);
	virtual bool SetLinkDraggable(bool linkDraggable);
	virtual bool SetMoveDraggable(bool moveDraggable);
	virtual ZafLogicalColor SetTextColor(ZafLogicalColor color, ZafLogicalColor mono = ZAF_MONO_NULL);

	// --- Advanced event handling ---
#	if defined(ZAF_MACINTOSH)
	virtual ZafEventType DispatchMouseEvent(const ZafEventStruct &event);
#	elif defined(ZAF_INDEPENDENT) || defined(ZAF_CURSES)
	virtual ZafEventType DispatchMouseEvent(const ZafEventStruct &event);
	virtual ZafWindowObject *FindMouseObject(const ZafEventStruct &event);
#	endif

	// --- List members ---
	virtual ZafWindowObject *Add(ZafWindowObject *object, ZafWindowObject *position = ZAF_NULLP(ZafWindowObject));
	ZafTreeItem *Current(void) const { return((ZafTreeItem *)current); }
	ZafTreeItem *First(void) const { return((ZafTreeItem *)first); }
	ZafTreeItem *Last(void) const { return((ZafTreeItem *)last); }
	virtual ZafCompareFunction SetCompareFunction(ZafCompareFunction compareFunction);
	virtual void Sort(void);
	virtual ZafWindowObject *Subtract(ZafWindowObject *object);

	ZafTreeList &operator+(ZafWindowObject *object) { Add(object); return(*this); }
	ZafTreeList &operator-(ZafWindowObject *object) { Subtract(object); return(*this); }

	// --- Class identification ---
	static ZafClassID classID;
	static ZafClassNameChar ZAF_FARDATA className[];
	virtual ZafClassID ClassID(void) const { return (classID); }
	virtual ZafClassName ClassName(void) const { return (className); }
	virtual bool IsA(ZafClassID compareID) const;
	virtual bool IsA(ZafClassName compareName) const;

	// --- Specialty functions ---
	virtual ZafPositionStruct ConvertToOSPosition(const ZafWindowObject *object,
		const ZafPositionStruct *zafPosition = ZAF_NULLP(ZafPositionStruct)) const;
	virtual ZafPositionStruct ConvertToZafPosition(const ZafWindowObject *object,
		const ZafPositionStruct *osPosition = ZAF_NULLP(ZafPositionStruct)) const;

	// --- Special OS members ---
	virtual OSWindowID OSScreenID(ZafScreenIDType type = ZAF_SCREENID) const;

#	if defined(ZAF_INDEPENDENT) || defined(ZAF_CURSES)
//	virtual void OSUpdateRegions(ZafRegionList *regionList);
	virtual void ModifyOSShift(ZafPositionStruct &osPosition);
	virtual void OSDrawChildren(ZafRegionList *regionList);
#	endif

	// --- Advanced class members ---
#if defined(ZAF_MSWINDOWS) && defined(ZAF_WIN32)
	ZafTreeImageList *ImageList(void) { return (imageList); }
#endif

protected:
	friend class ZAF_EXPORT OSTreeList;

	bool autoSortData;
	bool drawLines;

	// --- General members ---
	virtual ZafEventType DragDropEvent(const ZafEventStruct &event);
	virtual ZafEventType Draw(const ZafEventStruct &event, ZafEventType ccode);
	virtual ZafEventType DrawFocus(ZafRegionStruct &region, ZafEventType ccode);
	virtual ZafEventType MoveEvent(const ZafEventStruct &event);
	virtual ZafEventType ScrollEvent(const ZafEventStruct &event);
	virtual const ZafPaletteStruct *MapClassPalette(ZafPaletteType type, ZafPaletteState state);
	virtual ZafWindowObject *NotifySelection(ZafWindowObject *object, bool selected);

#if defined(USE_ZAF_PERSISTENCE)
	// --- Persistent members ---
	void ReadData(ZafObjectPersistence &persist);
	virtual ZafObjectConstructor ReadFunction(void) { return (ZafTreeList::Read); }
	void WriteData(ZafObjectPersistence &persist);
#endif

	// --- Special OS members ---
	virtual void OSDestroy(void);
	virtual ZafEventType OSEvent(const ZafEventStruct &event);
	virtual void OSMapPalette(ZafPaletteStruct &palette, ZafPaletteType type, ZafPaletteState state);
	virtual void OSRegisterObject(void);

private:
	friend class ZAF_EXPORT ZafTreeItem;

	static ZafEventMap ZAF_FARDATA defaultEventMap[];
	static ZafPaletteMap ZAF_FARDATA defaultPaletteMap[];

	ZafTreeItem *firstVisible;
	ZafTreeItem *lastVisible;

#	if defined(ZAF_MSWINDOWS)
	bool ItemInView(ZafTreeItem *item);
	void ResizeVisibleItems(ZafTreeItem *startItem);
#		if defined(ZAF_WIN32)
	ZafTreeImageList *imageList;
#		endif
#	elif defined(ZAF_MOTIF)
	int itemWidth, itemHeight;
	ZafTreeItem *cancelObject, *viewCurrent;
	void CheckMembers(ZafTreeItem *item);
	void ComputeNextPosition(ZafTreeItem *object, int &column, int &line);
	void ComputePreviousPosition(ZafTreeItem *object, int &column, int &line);
#	elif defined(ZAF_INDEPENDENT) || defined(ZAF_CURSES) || defined(ZAF_MACINTOSH)
	bool ItemInView(ZafTreeItem *item);
	void ResizeVisibleItems(ZafTreeItem *startItem);
	ZafTreeItem *viewCurrent;
#	endif
};

// --- inline functions ---
inline bool ZafTreeList::AutoSortData(void) const { return (autoSortData); }
inline bool ZafTreeList::DrawLines(void) const { return (drawLines); }

// --------------------------------------------------------------------------
// ----- ZafTreeItem --------------------------------------------------------
// --------------------------------------------------------------------------

class ZAF_EXPORT ZafTreeItem : public ZafWindow
{
public:
	// --- General members ---
	ZafTreeItem(ZafBitmapData *normalBitmap, ZafBitmapData *selectedBitmap,
		const ZafIChar *text);
	ZafTreeItem(ZafBitmapData *normalBitmap, ZafBitmapData *selectedBitmap,
		ZafStringData *stringData);
	ZafTreeItem(const ZafTreeItem &copy);
	virtual ~ZafTreeItem(void);
	ZafTreeList *TreeList(void) const;

	// view access
	ZafTreeItem *ViewCurrent(void);
	ZafTreeItem *ViewFirst(void);
	ZafTreeItem *ViewLast(void);
	int ViewLevel(void);
	ZafTreeItem *ViewNext(ZafTreeItem *start = 0);
	ZafTreeItem *ViewPrevious(void);
	// depth access
	ZafTreeItem *DepthFirst(void);
	ZafTreeItem *DepthCurrent(void);
	ZafTreeItem *DepthLast(void);
	ZafTreeItem *DepthNext(ZafTreeItem *start = 0);
	ZafTreeItem *DepthPrevious(void);

	// --- Persistent members ---
	virtual ZafWindowObject *Duplicate(void);
#if defined(USE_ZAF_PERSISTENCE)
	ZafTreeItem(const ZafIChar *name, ZafObjectPersistence &persist);
	static ZafElement *Read(const ZafIChar *name, ZafObjectPersistence &persist);
	virtual void Write(ZafObjectPersistence &persist);
#endif

	// --- Attributes & data access ---
	// get
	bool AutoSortData(void) const;
	bool Expandable(void) const;
	bool Expanded(void) const;
	ZafBitmapData *NormalBitmap(void) const;
	ZafBitmapData *SelectedBitmap(void) const;
	ZafStringData *StringData(void) const;
	// set
	virtual bool SetAutoSortData(bool autoSortData);
	virtual bool SetExpandable(bool expandable);
	virtual bool SetExpanded(bool expanded);
	virtual ZafError SetNormalBitmap(ZafBitmapData *normalBitmap);
	virtual ZafError SetSelectedBitmap(ZafBitmapData *selectedBitmap);
	virtual ZafSelectionType SetSelectionType(ZafSelectionType selectionType);
	virtual ZafError SetStringData(ZafStringData *stringData);
	// toggle
	virtual bool ToggleExpanded(void);

	// --- Window members ---
	virtual bool SetDestroyable(bool destroyable);
	virtual bool SetLocked(bool locked);
	virtual bool SetMaximized(bool maximized);
	virtual bool SetMinimized(bool minimized);
	virtual bool SetModal(bool modal);
	virtual bool SetMoveable(bool moveable);
	virtual bool SetNormalHotKeys(bool normalHotKeys);
	virtual ZafWindow *SetOwner(ZafWindow *owner);
	virtual bool SetSizeable(bool sizeable);
	virtual bool SetTemporary(bool temporary);

	// --- Window object members ---
	virtual ZafRegionStruct ConvertToDrawRegion(const ZafWindowObject *object,
		const ZafRegionStruct *zafRegion = ZAF_NULLP(ZafRegionStruct)) const;
	virtual bool CopyDraggable(void) const;
	virtual bool Draggable(void) const;
	virtual ZafEventType Event(const ZafEventStruct &event);
	virtual ZafWindowObject *FocusObject(void) const;
	virtual bool LinkDraggable(void) const;
	virtual bool MoveDraggable(void) const;
	virtual ZafPaletteState PaletteState(void);
	virtual bool SetAcceptDrop(bool acceptDrop);
	virtual bool SetBordered(bool bordered);
	virtual bool SetFocus(bool currentFocus);
	virtual bool SetParentDrawBorder(bool parentDrawBorder);
	virtual bool SetParentDrawFocus(bool parentDrawFocus);
	virtual ZafRegionType SetRegionType(ZafRegionType regionType);
	virtual bool SetSelected(bool selected);
	virtual ZafError SetText(const ZafIChar *text);
	virtual const ZafIChar *Text(void);

	// --- List members ---
	virtual ZafWindowObject *Add(ZafWindowObject *object, ZafWindowObject *position = ZAF_NULLP(ZafWindowObject));
	ZafTreeItem *Current(void) const { return((ZafTreeItem *)current); }
	ZafTreeItem *First(void) const { return((ZafTreeItem *)first); }
	ZafTreeItem *Last(void) const { return((ZafTreeItem *)last); }
	ZafTreeItem *Next(void) const { return((ZafTreeItem *)next); }
	ZafTreeItem *Previous(void) const { return((ZafTreeItem *)previous); }
	virtual ZafCompareFunction SetCompareFunction(ZafCompareFunction compareFunction);
	virtual void Sort(void);
	virtual ZafWindowObject *Subtract(ZafWindowObject *object);

	ZafTreeItem &operator+(ZafWindowObject *object) { Add(object); return(*this); }
	ZafTreeItem &operator-(ZafWindowObject *object) { Subtract(object); return(*this); }

	// --- Class identification ---
	static ZafClassID classID;
	static ZafClassNameChar ZAF_FARDATA className[];
	virtual ZafClassID ClassID(void) const { return (classID); }
	virtual ZafClassName ClassName(void) const { return (className); }
	virtual bool IsA(ZafClassID compareID) const;
	virtual bool IsA(ZafClassName compareName) const;

#	if defined(ZAF_INDEPENDENT) || defined(ZAF_CURSES)
	virtual void OSInvalidateRegion(ZafRegionStruct *region, bool immediateRedraw = false, bool client = false);
#	endif
protected:
	friend class ZAF_EXPORT OSTreeList;
	friend class ZAF_EXPORT ZafTreeList;

	// --- General members ---
	ZafStringData *stringData;
	ZafBitmapData *normalBitmap;
	ZafBitmapData *selectedBitmap;
	ZafRegionStruct expandRegion, bitmapRegion, textRegion;

	bool autoSortData;
	bool expandable;
	bool expanded;

	virtual ZafPositionStruct ConvertToOSPosition(const ZafWindowObject *object,
		const ZafPositionStruct *zafPosition = ZAF_NULLP(ZafPositionStruct)) const;
	virtual ZafPositionStruct ConvertToZafPosition(const ZafWindowObject *object,
		const ZafPositionStruct *osPosition = ZAF_NULLP(ZafPositionStruct)) const;
	virtual ZafEventType DragDropEvent(const ZafEventStruct &event);
	virtual ZafEventType DrawFocus(ZafRegionStruct &region, ZafEventType ccode);
	virtual ZafEventType Draw(const ZafEventStruct &event, ZafEventType ccode);
	virtual void GetClip(ZafWindowObject *object, ZafRegionStruct &clip, ZafRegionStruct &viewPort);
	virtual const ZafPaletteStruct *MapClassPalette(ZafPaletteType type, ZafPaletteState state);
	virtual ZafRegionStruct MaxRegion(ZafWindowObject *object,
		ZafVtJustify vWeight = ZAF_VT_TOP, ZafHzJustify hWeight = ZAF_HZ_LEFT);
	virtual ZafWindowObject *NotifyFocus(ZafWindowObject *object, bool focus);
	virtual ZafWindowObject *NotifySelection(ZafWindowObject *object, bool selected);

	// --- Special OS members ---
	virtual void OSDestroy(void);
	virtual ZafEventType OSEvent(const ZafEventStruct &event);
	virtual void OSRegisterObject(void);
	virtual OSWindowID OSScreenID(ZafScreenIDType type = ZAF_SCREENID) const;
	virtual void OSSize(void);
	static ZafError Update(ZafTreeItem *item, ZafUpdateType type);

#if defined(USE_ZAF_PERSISTENCE)
	// --- Persistent members ---
	void ReadData(ZafObjectPersistence &persist);
	virtual ZafObjectConstructor ReadFunction(void) { return (ZafTreeItem::Read); }
	void WriteData(ZafObjectPersistence &persist);
#endif

	// --- Image support ---
	static char ZAF_FARDATA expandName[];
	static char ZAF_FARDATA compressName[];
	static ZafBitmapData *expandBitmap;
	static ZafBitmapData *compressBitmap;
	static void ImageAllocate(void);
	static void ImageFree(bool globalRequest = false);

private:
	static ZafPaletteMap ZAF_FARDATA defaultPaletteMap[];

#	if defined(ZAF_MOTIF)
	void CheckMembers(ZafTreeItem *item);
#	endif
};

// --- inline functions ---
inline bool ZafTreeItem::AutoSortData(void) const { return (autoSortData); }
inline bool ZafTreeItem::Expandable(void) const { return (expandable); }
inline bool ZafTreeItem::Expanded(void) const { return (expanded); }
inline ZafBitmapData *ZafTreeItem::NormalBitmap(void) const { return (normalBitmap); }
inline ZafBitmapData *ZafTreeItem::SelectedBitmap(void) const { return (selectedBitmap); }

#endif // Z_TREE_HPP

