#pragma once
#include "CellBorder.h"
#include "Cell2MapEventsImpl.h"
#include <map>
#include <vector>
using namespace std;
namespace mycell{
//class GridBase;
struct BorderPair
{
Border left,top,right,bottom;
BorderPair()
{
clear();
}
void clear()
{
left.SetNull();
top.SetNull();
right.SetNull();
bottom.SetNull();
}
bool empty()const
{
return left.IsNull() && top.IsNull() && right.IsNull() && bottom.IsNull();//return !HasRight() && !HasBottom();
}
};
class GridBorders : public Cell2MapEventsImpl<BorderPair>
{
private:
BorderPair* find(int row,int col)
{
map<row_t,map<col_t,BorderPair>*>::iterator it=maps_.find(row);
if(it!=maps_.end()){
map<col_t,BorderPair>& mi=*it->second;
map<col_t,BorderPair>::iterator i=mi.find(col);
if(i!=mi.end()){
return &i->second;
}
}
return NULL;
}
BorderPair const* find(int row,int col)const
{
map<row_t,map<col_t,BorderPair>*>::const_iterator it=maps_.find(row);
if(it!=maps_.end()){
map<col_t,BorderPair>& mi=*it->second;
map<col_t,BorderPair>::iterator i=mi.find(col);
if(i!=mi.end()){
return &i->second;
}
}
return NULL;
}
public:
BOOL HasBorders()const
{
for(map<row_t,map<col_t,BorderPair>*>::const_iterator it=maps_.begin();it!=maps_.end();++it)
{
map<col_t,BorderPair>& mi=*it->second;
for(map<col_t,BorderPair>::const_iterator i=mi.begin();i!=mi.end();++i)
{
if(!i->second.empty())
return TRUE;
}
}
return FALSE;
}
BOOL GetBorder(int row,int col,BorderPair& borderPair)const
{
_ASSERT(borderPair.empty());
BorderPair const* p=find(row,col);
if(p){
borderPair=*p;
return TRUE;
}else
return FALSE;
}
//do not delete the return value
void GetRightBottomBorder(int row,int col,BorderPair& borderPair)const
{
//borderPair.clear();
_ASSERT(borderPair.empty());
BorderPair const* p=find(row,col);
if(p){
borderPair.right=p->right;
borderPair.bottom=p->bottom;
}
if(borderPair.right.IsNull()){
if(p=find(row,col+1))
borderPair.right=p->left;
}
if(borderPair.bottom.IsNull()){
if(p=find(row+1,col))
borderPair.bottom=p->top;
}
}
BOOL GetLeftBorder(int row,int col,Border& border)
{
border.SetNull();
BorderPair* p=find(row,col);
if(p){
border=p->left;//return p->get_left(border);
}
if(border.IsNull() && col>0){
p=find(row,col-1);
if(p)
border=p->right;
}
return !border.IsNull();
}
BOOL GetTopBorder(int row,int col,Border& border)
{
border.SetNull();
BorderPair* p=find(row,col);
if(p){
border=p->top;//return p->get_left(border);
}
if(border.IsNull() && row>0){
p=find(row-1,col);
if(p)
border=p->bottom;
}
return !border.IsNull();
}
BOOL GetRightBorder(int row,int col,Border& border)
{
border.SetNull();
BorderPair* p=find(row,col);
if(p){
border=p->right;
}
if(border.IsNull()){
if(p=find(row,col+1))
border=p->left;
}
return !border.IsNull();
}
BOOL GetBottomBorder(int row,int col,Border& border)
{
border.SetNull();
BorderPair* p=find(row,col);
if(p){
border=p->bottom;
}
if(border.IsNull()){
if(p=find(row+1,col))
border=p->top;
}
return !border.IsNull();
}
void SetBorder(int row,int col,Border left,Border top,Border right,Border bottom)
{
SetLeftBorder(row,col,left);
SetTopBorder(row,col,top);
SetRightBorder(row,col,right);
SetBottomBorder(row,col,bottom);
}
void SetLeftBorder(int row,int col,Border border);
void SetTopBorder(int row,int col,Border border);
void ClearLeftBorder(int row,int col);
//void SetTopBorder(int row,int col,Border border);
//{
// SetBottomBorder(row-1,col,border);
//}
void ClearTopBorder(int row,int col);
void SetRightBorder(int row,int col,Border border);
void ClearRightBorder(int row,int col);
void SetBottomBorder(int row,int col,Border border);
void ClearBottomBorder(int row,int col);
//{
// /*old
// BorderPair* p=find(row,col);
// if(p){
// p->clear_bottom();
// }
// //ClearTopBorder(row+1,col);
// */
// map<row_t,map<col_t,BorderPair>*>::iterator it=maps_.find(row);
// if(it!=maps_.end()){
// map<col_t,BorderPair>& mi=*it->second;
// map<col_t,BorderPair>::iterator i=mi.find(col);
// if(i!=mi.end()){
// i->second.clear_bottom();
// if(!i->second.HasRight()){
// mi.erase(i);
// if(mi.empty()){
// delete it->second;
// maps_.erase(it);
// }
// }
// }
// }
//}
/*
public:
void OnRowDelete(int beg,int end)
{
_ASSERT(end>=beg);
//map<row_t,map<col_t,BorderPair>*> maps_;
typedef map<col_t,BorderPair>* second_t;
vector<pair<row_t,second_t> > vec;
int const cnt=end-beg+1;
for(map<row_t,second_t>::iterator it=maps_.begin();it!=maps_.end();)
{
if(it->first>=beg && it->first<=end){
maps_.erase(it);
it=maps_.begin();
continue;
}else if(it->first>end){
vec.push_back(make_pair(it->first-cnt,it->second));
maps_.erase(it);
it=maps_.begin();
continue;
}
++it;
}
for(vector<pair<row_t,second_t> >::const_iterator it=vec.begin();it!=vec.end();++it)
{
maps_.insert(*it);
}
}
void OnRowInsertFront(int row,int nCount)
{
//map<row_t,map<col_t,BorderPair>*> maps_;
typedef map<col_t,BorderPair>* second_t;
vector<pair<row_t,second_t> > vec;
for(map<row_t,second_t>::iterator it=maps_.begin();it!=maps_.end();)
{
if(it->first>=row){
vec.push_back(make_pair(it->first+nCount,it->second));
it=maps_.erase(it);
continue;
}
++it;
}
for(vector<pair<row_t,second_t> >::const_iterator _i=vec.begin();_i!=vec.end();++_i)
{
maps_.insert(*_i);
}
}
void OnColDelete(int beg,int end)
{
//map<row_t,map<col_t,BorderPair>*> maps_;
_ASSERT(end>=beg);
int const cnt=end-beg+1;
//typedef map<col_t,BorderPair> second_t;
typedef BorderPair second_t;
vector<pair<col_t,second_t> > vec;
for(map<row_t,map<col_t,second_t>*>::iterator it=maps_.begin();it!=maps_.end();++it)
{
for(map<col_t,second_t>::iterator i=it->second->begin();i!=it->second->end();)
{
if(i->first>=beg && i->first<=end){
i=it->second->erase(i);
continue;
}else if(i->first>end){
vec.push_back(make_pair(i->first-cnt,i->second));
i=it->second->erase(i);
continue;
}
++i;
}
for(vector<pair<col_t,second_t> >::const_iterator _i=vec.begin();_i!=vec.end();++_i)
{
it->second->insert(*_i);
}
vec.clear();
}
}
void OnColInsertFront(int col,int nCount)
{
//map<row_t,map<col_t,BorderPair>*> maps_;
typedef BorderPair second_t;
vector<pair<col_t,second_t> > vec;
for(map<row_t,map<col_t,second_t>*>::iterator it=maps_.begin();it!=maps_.end();++it)
{
for(map<col_t,second_t>::iterator i=it->second->begin();i!=it->second->end();)
{
int const _col=i->first;
if(_col>=col){
vec.push_back(make_pair(_col+nCount,i->second));
i=it->second->erase(i);
continue;
}
++i;
}
for(vector<pair<col_t,second_t> >::const_iterator _i=vec.begin();_i!=vec.end();++_i)
{
it->second->insert(*_i);
}
vec.clear();
}
}
*/
};
}//namespace mycell