#ifndef __SPACES_H__
#define __SPACES_H__

#include <vector>
#include <set>
#include <map>

using namespace std;

#include "ChipMonkTypes.h"

#include "RectElementMapping.h"

struct CSpace : public CRect{
	set<int> m_setVSepIndx;
	int m_nId;
	int m_nLineIndx;
	bool m_bProjectBack;
	int m_nLineHeight;
	bool m_bSplit;

	set<CSpace*> m_setDowns, m_setUps;

	inline int GetId()const{return m_nId;}
	inline int GetLineId()const{return m_nLineIndx;}
	inline int Left()const{return left;}
	inline void AddUpNeighbor(CSpace *pSp){m_setUps.insert(pSp);}
	inline void AddDownNeighbor(CSpace *pSp){m_setDowns.insert(pSp);}
	inline set<CSpace*> & GetUpNeighbors(){return m_setUps;}
	inline set<CSpace*> & GetDownNeighbors(){return m_setDowns;}

	CSpace(const CRect &rect, int nLineIndx) : 
	CRect(rect), 
		m_nId(0),
		m_nLineIndx(nLineIndx), 
		m_bProjectBack(true),
		m_nLineHeight(0),
		m_bSplit(false){
	}

	CSpace(const CSpace & cspace) : CRect(cspace), 
		m_nId(cspace.m_nId),
		m_nLineIndx(cspace.m_nLineIndx),
		m_bProjectBack(true),
		m_nLineHeight(cspace.m_nLineHeight),
		m_bSplit(cspace.m_bSplit){
	}

	int GetXOverlap(const CSpace * pSp, int & nLeft, int & nRight)const{
		nLeft = max(left, pSp->left);
		nRight = min(right, pSp->right);
		return nRight - nLeft;
	}

	int GetXOverlap(const CSpace * pSp)const{
		int nLeft = max(left, pSp->left);
		int nRight = min(right, pSp->right);
		return nRight - nLeft;
	}

	int Overlap(const int* pImg, int nWidth, int nHeight, int nScale){
		CRect rect(left/nScale, top/nScale, right/nScale, bottom/nScale);
		if(rect.right >= nWidth || rect.bottom >= nHeight) return TRUE;
		const int *pStart = pImg + rect.top * nWidth + rect.left;
		const int *pEnd = pStart + rect.Height() * nWidth;
		for(; pStart < pEnd; pStart += nWidth){
			for(const int *pC = pStart, *pCend = pStart + rect.Width(); pC < pCend; ++pC){
				if(*pC < 0){
					return - *pC;
				}
			}
		}
		return 0;
	}

	inline bool IsProjected()const{return m_bProjectBack;}

	inline void SetProjectBack(bool bProjectBack){ m_bProjectBack = bProjectBack;}

	inline void SetLineHeight(int nLineHeight){m_nLineHeight = nLineHeight;}
	inline int GetLineHeight()const{return m_nLineHeight;}
	inline bool GetSplit()const{return m_bSplit;}
	inline void  SetSplit(bool bSplit){
		m_bSplit = bSplit;
	}
	inline void SetId(int nId){m_nId = nId;}
};

class IsLefterThan {
public:
	bool operator() (const CRect *a, const CRect *b) const{ 
		return (a->left < b->left); 
	}
};

void FillIndexRect(int *pImg, int nWidth, int nHeight, CRect rect, int nIndx);

struct CSpaces : public vector<CSpace *> {
	multimap<int, Vertice> m_mapH;
	CSpaces(){push_back(NULL);}
	~CSpaces(){}

	void Add2Map(CRect rect, int nId){
		m_mapH.insert(pair<int, Vertice>(rect.left, Vertice(nId, TRUE)));
		m_mapH.insert(pair<int, Vertice>(rect.right, Vertice(nId, FALSE)));
	}

	inline const multimap<int, Vertice>  & GetHorizontalMap()const{return m_mapH;}

	void clear(){ erase(begin() + 1, end()); m_mapH.clear();}

	void ProjectBack(int *pBp, int nWidth, int nHeight)const{
		for(const_iterator i = begin(); i != end(); ++i){
			if(*i && (*i)->m_bSplit){
			}
		}
	}


};


template <class T>
class IsRighterThan {
public:
	bool operator() (const  T *a, const  T *b) const{ 
		return (a->Left() >  b->Left()); 
	}
};

#endif //__SPACES_H__
