#ifndef _EXPANSE_H
#define _EXPANSE_H


#include <queue>
#include <string>


using namespace std;



class KMap{

Cbuffer* cb;            // struktura nesouci pro dane signaly pro C-eleme Reset a Set
RegStavBuf* rs;         // ukazatel na regiony
int sizeCode;           // velikost kodu
string expStr;          // term pro ktery se provadi expanze
int stav;               

queue<string> mm;       // ER- a QR-
queue<string> pp;       // ER+ a QR+

int delka1;
int* pole1;


//-----------------------------------------------------------------------------      
// vyprazdneni mnozin
void flush(){
while(!mm.empty()) mm.pop();
while(!pp.empty()) pp.pop();
}


//-----------------------------------------------------------------------------      
// porovnoni danych kodu pozice udava index, ktery se ma vynechat
int cmpStr(string* s1, string* s2, int posPrvni){

for(int i = sizeCode; i >= posPrvni; --i )
if(s1[i] != s2[i]) return 0;

return 1;

}

public:      

KMap(RegStavBuf* rss,int* pole,int delka, Cbuffer* c){
cb = c;
pole1 = pole;
delka1 = delka;
rs = rss;
start();
}


//-----------------------------------------------------------------------------      
// naplni mnoziny mm a pp prislusnzmi regiony regiony ER a QR
void naplQueue(RegStav* r){

for(int i = 0;i < r->pqrm;++i)
mm.push(r->qrms[i]);

for(int i = 0;i < r->pqrp;++i)
pp.push(r->qrps[i]);

for(int i = 0;i < r->perm;++i)
mm.push(r->erms[i]);

for(int i = 0;i < r->perp;++i)
pp.push(r->erps[i]);
     

}


//-----------------------------------------------------------------------------      
// fce prochzejici regiony pro dane signali a spousti expanzi, plni vyslednou strukturu
void start(){
int test = 0;

for(int i = 0; i < rs->pocet;++i){

//cyklus vybira vystupni a interni signaly
for(int j = 0;j < delka1;++j){
if(pole1[j] == i) {test = 1;break;}
}

if(test){
naplQueue(&(rs->rs[i]));
Celem c;
c.posPr = i;

// vybyra stavi pro expazi z ER+
for(int g = 0;g < rs->rs[i].perp;++g){
sizeCode = rs->rs[i].erps[g].size();
expStr = rs->rs[i].erps[g];
fceExpanze(mm,expStr,sizeCode);
c.set  = expStr;
//cout << expStr << endl;
}


//vybyra stavy pro expanzi z ER-
for(int g = 0;g < rs->rs[i].perm;++g){
sizeCode = rs->rs[i].erms[g].size();
expStr = rs->rs[i].erms[g];
fceExpanze(pp,expStr,sizeCode);
c.reset  = expStr;
//cout <<expStr << endl;
}

cb->vect.push_back(c);
flush();
//cout << endl;
test = 0;     
}

}

}


//-----------------------------------------------------------------------------      
//expanze    FIFO codu, vzorovy kod, delka kodu
void fceExpanze(queue<string>& q,string& s1, int delka){

string s2;                     // vysledek
string tmp1;
string tmp2;
int* k =  new  int[delka];


for(int i= 0; i < int(s1.size());  i ++){

for(int j = 0; j < int(q.size()) ; j++){

s2 = q.front();

if(i != int(s1.size()) - 1){       // do predosledniho vzorku
k[i] = 1;
tmp1 = s1.substr(i + 1);      //substring ke zkoumani
tmp2 = s2.substr(i + 1);
if(!tmp1.compare(tmp2)) { 

int te = 1;
for(int f = 0; f < i;f++){
if(k[f] == 0)
if(s1[f] != s2[f]){
te = 0;
break;
}
}

if(te){
k[i]=0;
break;
}
}
}else{



k[i] = 1;
int te = 0;
for(int f = 0; f < i;f++){
if(k[f] == 0)
if(s1[f] == s2[f]){
te = 1;
break;
}
}

if(te){
k[i]=0;
break;
}

}


q.push(q.front());
q.pop();
}

}

int cista = 0;
for(int g = 0;g < int(s1.size());g++){
if(cista == int(s1.size()) - 1) break;
if(k[g] == 1){ 
s1[g] = '-';
cista++;
}
}

delete [] k;
     
}

    


      
};

#endif
