#ifndef INCL_MULTILISTVIEW_H
#define INCL_MULTILISTVIEW_H

/*-----------------------------------------------------------------------
 * Xclasses header file
 * 
 * Copyright (C) 1998 Jürgen Schmitz
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 *-----------------------------------------------------------------------
 */

#include <Xclasses/types.h>
#include <Xclasses/gadget.h>
#include <Xclasses/Xcolors.h>
#include <Xclasses/Ddraw.h>
#include <Xclasses/gfx_object.h>
#include <Xclasses/callable.h>


class multilistview : public gadget, private Ddraw
{
	friend class pmultilistview;

	class pmultilistview *p;

public:
    virtual void GExpose(XEvent *event);
    virtual void GActionPress(int mx,int my,int rx,int ry,unsigned int state,int button,int reason);
    virtual void GActionRelease(int mx,int my,int rx,int ry,unsigned int state,int button,int reason);
    virtual int  GMouseMove(int mx,int my,int rx,int ry,unsigned int state,int button);
    virtual int  GActivate(XEvent *event,int why);
    virtual int  GSelected(XEvent *event,int why,int wasabove);
	virtual void GSetLimits(void);

	int visible_width(void);
	int visible_height(void);

public:
    multilistview();
    virtual ~multilistview();

    virtual int Create(void);
    virtual void Free(void);
	virtual void Resize(int w,int h);
	virtual void Lock(void);
	virtual void Unlock(void);
	virtual void Block(int);
	virtual void Unblock(int);

// before Create	
	void Columns(int,struct column_spec spec[]);

	void ShowSelected(void);
	void ReadOnly(void);
	void Spacing(int);

// before & after
	void ColumnConfigure(int col,struct column_spec *);

	void MultiSelect(void);
	void DirectMulti(void);
	void SingleSelect(void);

// item management
	void AddAtEnd(char **);
	void AddAtBegin(char **);
	void AddBefore(int,char **);

	void AddAtEnd(char **,void *data);
	void AddAtBegin(char **,void *data);
	void AddBefore(int,char **,void *data);

	void Remove(int);
	void Remove(int start,int end);
	void RemoveAll(void);
	void Replace(int,char **);
	void Replace(int,int,char *);
	void MoveLine(int,int);
	int Count();

	void *GetData(int);
	void ChangeData(int,void *data);

// item settings
	void LockItem(int);
	void UnlockItem(int);
	void MarkItem(int);
	void UnmarkItem(int);

// multi selection
	int FindNextMarked(int);
	int IsMarked(int);

// visible part
	void Top(int);
	int Top(void);
	void Selected(int);
	int Selected(void);

	int SelectedColumns(void);
};


struct column_spec
{
	unsigned int	flags;

	unsigned int	weight;	// percent
	unsigned int	width;	// multiples of line height *10 - ie. number of chars*10 with a fixed width font
	int         	adjust; // ADJUST_LEFT, ...

	char *title;

	// column hook
	callable *hookclass;
	union
	{
		int (*hook)(struct hook_data*);
		int (callable::*objhook)(struct hook_data*);
	};
	void *userdata;
 		// int Hook(struct hook_data*, void*)
 		// returns space of painted object
 		// if negativ old output colors are restored
};

#define CSF_USEWEIGHT		0x00000001	// not allowed with CSF_USEWIDTH
#define CSF_USEWIDTH		0x00000002	// not allowed with CSF_USEWEIGHT
#define CSF_SELECTABLE		0x00000004
#define CSF_NOTSELECTABLE	0x00000008
#define CSF_HOOK			0x00000010
#define CSF_ADJUST			0x00000020
#define CSF_TITLE			0x00000040
#define CSF_USESHORTCUT		0x00000080
#define CSF_SCALEABLE		0x00000100
#define CSF_AUTOSCALE		0x00000200

#define HOOKDATAVERSION	2

#define HD_SELECTED	0x00000001
#define HD_MARKED	0x00000002
#define HD_LOCKED	0x00000004

struct hook_data
{
	int			version;
	int			number;
	int			column;
	int			x;
	int			y;
	int			width;
	int			height;
	int			flags;
	gadget		*drawable;
	multilistview	*list;
	void		*itemdata;
	void		*userdata;
};

// -------------------------------------------------------------------
// some nice service functions for GUIs:
// -------------------------------------------------------------------

void lv_remove(class multilistview *,void *cl,void f(void *));
void lv_remove(class multilistview *,callable *cl,void (callable::*f)(void *));
		// removes the selected or all marked lines and
		// calls for each f with the GetData() result
void lv_moveUp(class multilistview *);
void lv_moveDown(class multilistview *);
		// moves the selected or all marked lines one line
		// up or down - if this is possible
void lv_forMarked(multilistview *lv,void *cl,void f(void *));
void lv_forMarked(multilistview *lv,callable *cl,void (callable::*f)(void *));
		// calls f for the selected or all marked lines


// -------------------------------------------------------------------
// typedefs (casts)
// -------------------------------------------------------------------

#define HOOKCAST int (callable::*)(struct hook_data*)
#define LVWORKCAST void (callable::*)(void *)

#endif
