/***************************************************************************
                          kimearea.h  -  description
                             -------------------
    begin                : Thu Jun 14 2001
    copyright            : (C) 2001 by Jan Schäfer
    email                : janschaefer@users.sourceforge.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 KIMEAREA_H
#define KIMEAREA_H

#include <tqrect.h>
#include <tqpoint.h>
#include <tqptrlist.h>
#include <tdelocale.h>
#include <tqmap.h>

#include "tdeversion.h"

class TQPainter;
class TQPointArray;
class TQListViewItem;
class TQBitmap;

typedef TQPtrList<TQRect> SelectionPointList;

typedef TQMap<TQString,TQString> AttributeMap;
typedef TQMapConstIterator<TQString,TQString> AttributeIterator;



class Area
{
public:
	enum ShapeType { None, Rectangle, Circle, Polygon, Default, Selection };
  static bool highlightArea;
  static bool showAlt;

protected:
	TQRect _rect;
	ShapeType _type;
	TQString _name;
	TQString _href;
	TQString _alt;
	TQString _target;
	AttributeMap _attributes;
	bool _isSelected;
	bool _finished;
	bool _isMoving;
	int currentHighlighted;
	TQListViewItem* _listViewItem;
	// Only used for Polygons
	TQPointArray *_coords;
	SelectionPointList *_selectionPoints;
	TQPixmap *_highlightedPixmap;
	
	void drawHighlighting(TQPainter & p);
	void drawAlt(TQPainter & p);
	TQString getHTMLAttributes() const;
	
public:
	Area();
	virtual ~Area();

	virtual Area* clone() const;	
	// Default implementation; is specified by subclasses
	virtual bool contains(const TQPoint &) const;
	// Default implementation; is specified by subclasses
	virtual TQString coordsToString() const;
	virtual void draw(TQPainter &);
	
	virtual TQBitmap getMask() const;	
	virtual	TQString getHTMLCode() const;
	
	virtual void setHighlightedPixmap( TQImage &, TQBitmap &);
	
	virtual void moveBy(int, int);
	virtual void moveTo(int, int);
	virtual void moveSelectionPoint(TQRect*, const TQPoint &);
	
	virtual TQRect* onSelectionPoint(const TQPoint &,double zoom) const;
	virtual bool removeSelectionPoint(TQRect * r);
  virtual SelectionPointList* selectionPoints() const { return _selectionPoints; }
	
	virtual TQRect rect() const;
	
	virtual TQRect selectionRect() const;
	virtual void setArea(const Area &);
	virtual bool setCoords(const TQString &);
	/** finished drawing only important for polygon */
	virtual void setFinished(bool b) { _finished=b; }
	virtual void setRect(const TQRect &);
  virtual void setMoving(bool b);
  virtual bool isMoving() const;
	// Default implementation; is specified by subclasses
	virtual TQString typeString() const { return ""; }
	virtual ShapeType type() const;
	
	virtual void updateSelectionPoints() {};

	// Only interesting for Polygons
	virtual void simplifyCoords() {};
	virtual int addCoord(const TQPoint &);
	virtual void insertCoord(int, const TQPoint &);
	virtual void removeCoord(int);
	virtual void moveCoord(int,const TQPoint &);
	virtual TQPointArray* coords() const;
	virtual void highlightSelectionPoint(int);

	virtual TQString attribute(const TQString &) const;
	virtual void setAttribute(const TQString &, const TQString &);
	virtual AttributeIterator firstAttribute() const;
	virtual AttributeIterator lastAttribute() const;
	
	TQPixmap cutOut(const TQImage &) ;		
	void setListViewItem(TQListViewItem*);
	void deleteListViewItem();
	TQListViewItem* listViewItem() const;
	void setName(const TQString &);
	TQString name() const;
	void setSelected(bool b);
	bool isSelected() const;
	bool finished() const;
	uint countSelectionPoints() const;

};



inline TQListViewItem* Area::listViewItem() const {
	return _listViewItem;
}

inline void Area::setName(const TQString & name) {
	_name=name;
}

inline TQString Area::name() const {
	return _name;
}

inline bool Area::isMoving() const {
  return _isMoving;
}


inline bool Area::isSelected() const {
	return _isSelected;
}


inline bool Area::finished() const {
	return _finished;
}

/**
 *	Represents a Rectangle Area
 **/
class RectArea : public Area
{
	public:
		RectArea();
		virtual ~RectArea();
		
		virtual Area* clone() const;	
		virtual bool contains(const TQPoint & p) const;
		virtual TQString coordsToString() const;
		virtual void draw(TQPainter & p);
		virtual void moveSelectionPoint(TQRect* selectionPoint, const TQPoint & p);
		virtual bool setCoords(const TQString & s);
		virtual TQString typeString() const { return i18n("Rectangle"); }
		virtual TQBitmap getMask() const;
		virtual	TQString getHTMLCode() const;		
		virtual void updateSelectionPoints();			
};


/**
 *	Represents a Circle Area
 **/
class CircleArea : public Area
{
	public:
		CircleArea();
		virtual ~CircleArea();

		virtual Area* clone() const; 	
		virtual bool contains(const TQPoint & p) const;
		virtual TQString coordsToString() const;
		virtual void draw(TQPainter & p);
		virtual void moveSelectionPoint(TQRect* selectionPoint, const TQPoint & p);
		virtual bool setCoords(const TQString & s);
		virtual void setRect(const TQRect & r);
		virtual TQString typeString() const { return i18n("Circle"); }
		virtual TQBitmap getMask() const;
		virtual TQString getHTMLCode() const;
		virtual void updateSelectionPoints();			

};

/**
 *	Represents a Rectangle Area
 **/
class PolyArea :public Area
{
	public:
		PolyArea();
		virtual ~PolyArea();

		virtual Area* clone() const;	
		virtual bool contains(const TQPoint & p) const;
		virtual TQString coordsToString() const;
		virtual void draw(TQPainter & p);
		virtual void moveSelectionPoint(TQRect* selectionPoint, const TQPoint & p);
		virtual void simplifyCoords();
  	virtual int addCoord(const TQPoint & p);
		virtual bool setCoords(const TQString & s);
		virtual TQRect selectionRect() const;		
		virtual void setFinished(bool b);
		virtual TQString typeString() const { return i18n("Polygon"); }
		virtual TQBitmap getMask() const;	
		virtual TQString getHTMLCode() const;
		virtual void updateSelectionPoints();			

  private:
   static int distance(const TQPoint &p1, const TQPoint &p2);
   static bool isBetween(const TQPoint &p, const TQPoint &p1, const TQPoint &p2);
		
};

/**
 *	Represents the default Area
 **/
class DefaultArea :public Area
{
	public:
		DefaultArea();
		virtual ~DefaultArea();
		
		virtual Area* clone() const;	
		// the default area isn't drawn
		virtual void draw(TQPainter & p);
		virtual TQString typeString() const { return i18n("Default"); }
		virtual TQString getHTMLCode() const;

};


typedef TQPtrList<Area> AreaList;
typedef TQPtrListIterator<Area> AreaListIterator;

/**
 *	This class represents a selection of areas
 *  all operations performed on this class
 *  will be performed on the selected Areas
 *  the only actions that can be used is the
 *  move action
 **/
class AreaSelection : public Area {
	public :
		AreaSelection();
		virtual ~AreaSelection();
		
		/**
		 * New Methods
		 */
		
		// Adding automatically selects the area
		void add(Area *a);
		
		// Removing automatically deselects the area
		void remove(Area *a);
		
		// Removes all areas from the list and deselects them
		void reset();
		
		uint count() const;
		
		AreaList getAreaList() const;
		AreaListIterator getAreaListIterator() const;
		void setAreaList( const AreaList & areas );
		
		bool isEmpty() const;

		/**
		 * Overiden Methods of the Area class
		 */		
		virtual bool contains(const TQPoint & p) const;

		/**
		 *
		 **/
		virtual TQRect* onSelectionPoint(const TQPoint & p, double zoom) const;
		
		/**
		 * Only if one Area is selected the moveSelectionPoint method
		 * of that Area will be called
		 **/
		virtual void moveSelectionPoint(TQRect* selectionPoint, const TQPoint & p);				
		
    virtual SelectionPointList* selectionPoints() const;
		
		/**
		 * All Areas will be moved by dx and dy
		 **/
		virtual void moveBy(int dx, int dy);

		/**
		 * Calls for every selected Area the setArea with the
		 * corresponding Area in the copy Selection.
		 * IMPORTANT : works only if the copy Area is an AreaSelection
		 * and have the same number of Areas
		 **/	
		virtual void setArea(const Area & copy);
		virtual void setAreaSelection(const AreaSelection & copy);
		
		/**
		 * If only one Area is selected the setRect method of that Area
		 * will be called
		 **/
		virtual void setRect(const TQRect & r);
		virtual TQRect rect() const;
		
				
		virtual TQString typeString() const;
		virtual ShapeType type() const;
		
		// The selection is only a container
		// so it is never drawn
		virtual void draw(TQPainter & p);
		
	
		/**
		 * A deep copy of the Areas
		 **/
		virtual Area* clone() const;	
		
		virtual void updateSelectionPoints();			
  	virtual int addCoord(const TQPoint & p);
  	virtual void insertCoord(int pos, const TQPoint & p);
  	virtual void removeCoord(int pos);
    virtual bool removeSelectionPoint(TQRect * r);  	
  	virtual void moveCoord(int pos,const TQPoint & p);
  	virtual TQPointArray* coords() const;
		virtual void highlightSelectionPoint(int);
		
		virtual TQRect selectionRect() const;

  	virtual TQString attribute(const TQString & name) const;
  	virtual void setAttribute(const TQString & name, const TQString & value);
  	virtual AttributeIterator firstAttribute() const;
  	virtual AttributeIterator lastAttribute() const;

    virtual void setMoving(bool b);
    virtual bool isMoving() const;
		
		
    bool allAreasWithin(const TQRect & r) const;

		// makes the cache invalid
		void invalidate();		
	private :
		
		AreaList *_areas;			
		
		// The selectionRect and the rect are cached
		// so even in const functions they must be changeable
		mutable TQRect _cachedSelectionRect;
		mutable TQRect _cachedRect;
		mutable bool _selectionCacheValid;
		mutable bool _rectCacheValid;
				
};


inline void AreaSelection::invalidate() {
	_selectionCacheValid=false;
	_rectCacheValid=false;
}

#endif


