/*! \file piscreentiles.h
 * \brief Various tiles for PIScreen
*/
/*
	PIP - Platform Independent Primitives
	Various tiles for PIScreen
	Ivan Pelipenko peri4ko@yandex.ru

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program 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 Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef PISCREENTILES_H
#define PISCREENTILES_H

#include "pip_console_export.h"
#include "piscreentile.h"


class PIP_CONSOLE_EXPORT TileSimple: public PIScreenTile {
	PIOBJECT_SUBCLASS(TileSimple, PIScreenTile)
public:
	typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
	TileSimple(const PIString & n = PIString());
	TileSimple(const Row & r);
	virtual ~TileSimple() {}
	PIVector<Row> content;
	PIScreenTypes::Alignment alignment;
protected:
	void sizeHint(int & w, int & h) const;
	void drawEvent(PIScreenDrawer * d);
};


class TileList;

class PIP_CONSOLE_EXPORT TileScrollBar: public PIScreenTile {
	PIOBJECT_SUBCLASS(TileScrollBar, PIScreenTile)
	friend class TileList;
public:
	TileScrollBar(const PIString & n = PIString());
	virtual ~TileScrollBar() {}
	void setMinimum(int v);
	void setMaximum(int v);
	void setValue(int v);
	int minimum() const {return minimum_;}
	int maximum() const {return maximum_;}
	int value() const {return value_;}
	int thickness;
protected:
	void _check();
	void sizeHint(int & w, int & h) const;
	void drawEvent(PIScreenDrawer * d);
	bool mouseEvent(PIKbdListener::MouseEvent me);
	int minimum_, maximum_, value_;
	PIChar line_char;
};


class PIP_CONSOLE_EXPORT TileList: public PIScreenTile {
	PIOBJECT_SUBCLASS(TileList, PIScreenTile)
public:
	enum SelectionMode {
		NoSelection,
		SingleSelection,
		MultiSelection
	};
	enum EventType {
		SelectionChanged,
		RowPressed
	};

	TileList(const PIString & n = PIString(), SelectionMode sm = NoSelection);
	virtual ~TileList() {}

	typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
	PIDeque<Row> content;
	PIScreenTypes::Alignment alignment;
	SelectionMode selection_mode;
	PISet<int> selected;
	int lhei, cur, offset;
protected:
	void sizeHint(int & w, int & h) const;
	void resizeEvent(int w, int h);
	void drawEvent(PIScreenDrawer * d);
	bool keyEvent(PIKbdListener::KeyEvent key);
	bool mouseEvent(PIKbdListener::MouseEvent me);
	bool wheelEvent(PIKbdListener::WheelEvent we);
	TileScrollBar * scroll;
	bool mouse_sel;
};


class PIP_CONSOLE_EXPORT TileButton: public PIScreenTile {
	PIOBJECT_SUBCLASS(TileButton, PIScreenTile)
public:
	TileButton(const PIString & n = PIString());
	virtual ~TileButton() {}
	enum EventType {
		ButtonClicked
	};
	PIScreenTypes::CellFormat format;
	PIString text;
protected:
	void sizeHint(int & w, int & h) const;
	void drawEvent(PIScreenDrawer * d);
	bool keyEvent(PIKbdListener::KeyEvent key);
	bool mouseEvent(PIKbdListener::MouseEvent me);
};




class PIP_CONSOLE_EXPORT TileButtons: public PIScreenTile {
	PIOBJECT_SUBCLASS(TileButtons, PIScreenTile)
public:
	TileButtons(const PIString & n = PIString());
	virtual ~TileButtons() {}
	enum EventType {
		ButtonSelected
	};
	typedef PIPair<PIString, PIScreenTypes::CellFormat> Button;
	PIScreenTypes::Alignment alignment;
	PIVector<Button> content;
	int cur;
protected:
	void sizeHint(int & w, int & h) const;
	void drawEvent(PIScreenDrawer * d);
	bool keyEvent(PIKbdListener::KeyEvent key);
	bool mouseEvent(PIKbdListener::MouseEvent me);
	struct Rect {
		Rect(int _x0 = 0, int _y0 = 0, int _x1 = 0, int _y1 = 0): x0(_x0),y0(_y0),x1(_x1),y1(_y1) {}
		int x0,y0,x1,y1;
	};
	PIVector<Rect> btn_rects;
};


class PIP_CONSOLE_EXPORT TileCheck: public PIScreenTile {
	PIOBJECT_SUBCLASS(TileCheck, PIScreenTile)
public:
	TileCheck(const PIString & n = PIString());
	virtual ~TileCheck() {}
	enum EventType {
		Toggled
	};
	PIScreenTypes::CellFormat format;
	PIString text;
	bool toggled;
protected:
	void sizeHint(int & w, int & h) const;
	void drawEvent(PIScreenDrawer * d);
	bool keyEvent(PIKbdListener::KeyEvent key);
	bool mouseEvent(PIKbdListener::MouseEvent me);
};


class PIP_CONSOLE_EXPORT TileProgress: public PIScreenTile {
	PIOBJECT_SUBCLASS(TileProgress, PIScreenTile)
public:
	TileProgress(const PIString & n = PIString());
	virtual ~TileProgress() {}
	PIScreenTypes::CellFormat format;
	PIString prefix;
	PIString suffix;
	double maximum;
	double value;
protected:
	void sizeHint(int & w, int & h) const;
	void drawEvent(PIScreenDrawer * d);
};


class PIP_CONSOLE_EXPORT TilePICout: public TileList {
	PIOBJECT_SUBCLASS(TilePICout, PIScreenTile)
public:
	TilePICout(const PIString & n = PIString());
	virtual ~TilePICout() {}
	PIScreenTypes::CellFormat format;
	int max_lines;
protected:
	void drawEvent(PIScreenDrawer * d);
	bool keyEvent(PIKbdListener::KeyEvent key);
};


class PIP_CONSOLE_EXPORT TileInput: public PIScreenTile {
	PIOBJECT_SUBCLASS(TileInput, PIScreenTile)
public:
	TileInput(const PIString & n = PIString());
	virtual ~TileInput() {}
	PIScreenTypes::CellFormat format;
	PIString text;
	int max_length;
protected:
	void sizeHint(int & w, int & h) const;
	void drawEvent(PIScreenDrawer * d);
	bool keyEvent(PIKbdListener::KeyEvent key);
	void reserCursor();
	int cur, offset;
	bool inv;
	PITimeMeasurer tm_blink;
};


#endif // PISCREENTILES_H
