void getPoolingOpt(cv::Mat fea, cv::Mat corr, cv::Mat xyz_lab, cv::Mat &centers, cv::Mat &ranges, float tt, float ratio)
{
    std::vector< std::vector<int> > pattern_idx = getPatterns(corr, tt);
    int len = pattern_idx.size();
    std::vector<cv::Mat> centers_vec(len);
    std::vector<cv::Mat> ranges_vec(len);
    
    #pragma omp parallel for schedule(dynamic, 1) 
    for( int i = 0 ; i < len ; i++ )
    {
        cv::Mat cur_xyz_lab = ext_pattern(fea, xyz_lab, pattern_idx[i], ratio);
        //int cur_K = 20 - pattern_idx[i].size();
        //if( cur_K <= 1 )
        //    cur_K = 2;
        int cur_K = 300;
        
        cv::Mat cur_center, cur_range;
        ext_pooling(cur_xyz_lab, cur_center, cur_range, cur_K);
        
        centers_vec[i] = cur_center;
        ranges_vec[i] = cur_range;
        //std::cerr << cur_range << std::endl;
    }
    
    cv::vconcat(centers_vec, centers);
    cv::vconcat(ranges_vec, ranges);
}
void getPoolingSep(cv::Mat fea, cv::Mat corr, cv::Mat xyz_lab, cv::Mat &xyz_center, cv::Mat &xyz_ranges, cv::Mat &lab_center, cv::Mat &lab_ranges, float tt, float ratio)
{
    int KK = 200;
    
    std::vector< std::vector<int> > pattern_idx = getPatterns(corr, tt);
    int len = pattern_idx.size();
    std::vector<cv::Mat> xyz_centers_vec(len);
    std::vector<cv::Mat> xyz_ranges_vec(len);
    std::vector<cv::Mat> lab_centers_vec(len);
    std::vector<cv::Mat> lab_ranges_vec(len);
    
    #pragma omp parallel for schedule(dynamic, 1) 
    for( int i = 0 ; i < len ; i++ )
    {
        cv::Mat cur_xyz_lab = ext_pattern(fea, xyz_lab, pattern_idx[i], ratio);
        
        cv::Mat cur_xyz = cur_xyz_lab.colRange(0, 3);
        cv::Mat cur_lab = cur_xyz_lab.colRange(3, 6);
        
        cv::Mat cur_xyz_center, cur_xyz_range, cur_lab_center, cur_lab_range;
        ext_pooling(cur_xyz, cur_xyz_center, cur_xyz_range, KK);
        ext_pooling(cur_lab, cur_lab_center, cur_lab_range, KK);
        
        xyz_centers_vec[i] = cur_xyz_center;
        xyz_ranges_vec[i] = cur_xyz_range;
        
        lab_centers_vec[i] = cur_lab_center;
        lab_ranges_vec[i] = cur_lab_range;
    }
    
    cv::vconcat(xyz_centers_vec, xyz_center);
    cv::vconcat(xyz_ranges_vec, xyz_ranges);
    
    cv::vconcat(lab_centers_vec, lab_center);
    cv::vconcat(lab_ranges_vec, lab_ranges);
}
int main (int argc, char **argv) {
	findPatternFlag = 0;
	std::string patternFile = "", patternStr = "";
	
	int c, color_flag = 0, help_flag = 0, edit_flag = 0, pattern_flag = 0, emax;
	
	while (1) {
		static struct option long_options[] = {
			{"help", no_argument, 0, 'h'},
			{"edit", required_argument, 0, 'e'},
			{"pattern", required_argument, 0, 'p'},
			{"color", no_argument, 0, 'c'},
			{0, 0, 0, 0}
		};
		// getopt_long guarda o indice da opcao aqui
		int option_index = 0;
		
		c = getopt_long (argc, argv, "che:p:", long_options, &option_index);
		
		// detecta o fim das opcoes
		if (c == -1) {
			break;
		}
		
		switch (c) {
			case 'c':
				color_flag = 1;
			break;
			case 'h':
				help_flag = 1;				
			break;
			case 'e':
				emax = atoi(optarg);
				edit_flag = 1;
			break;
			case 'p':
				// optarg eh o argumento da option;
				patternFile = std::string(optarg);
				pattern_flag = 1;
			break;
			default:
				abort();
		}
	}
	
	
	if (pattern_flag) {
		// pegando os padroes do arquivo
		wildcard = glob(patternFile);
		
		for(std::vector<std::string>::iterator itPF = wildcard.begin(); itPF != wildcard.end(); ++itPF) {
			getPatterns(*itPF);
		}
	}	
	
	for (int i = 1; i < argc; i++) {
		if(!equalsToOptions(argv[i])) {
			if((pattern_flag == 0) && (patternStr.compare("") == 0)) {
				// nao achou a patternFlag e pattern continua vazio
				patternStr = std::string(argv[i]);
			} else {				
				/*
				um pouco mais lento que o normal,
				mas ja garante o caso de wildcards
				*/
				wildcard = glob(std::string(argv[i]));

				for(int w = 0; w < wildcard.size(); w++) {
					textFiles.push_back(wildcard[w]);
				}
			}
		} else {
			// pula o proximo ja que toda opt tem argumento, exceto a color
			if (!(((tracoc.compare(argv[i])) == 0) || ((color.compare(argv[i])) == 0))) {
				i++;
			}
		}
	}

	// se o usuario n tiver utilizado -h, --help
	if(!help_flag) {
		// percorrendo pelo vector de arquivos texto
		for(std::vector<std::string>::iterator it = textFiles.begin() ; it != textFiles.end(); ++it) {
		// pegando o texto dentro do arquivo
			std::string file_string;
	
			char tab2[1024];
			strcpy(tab2, (*it).c_str());
			
			std::ifstream myfile (tab2);
			if (myfile.is_open()) {
				FsmAho fsmAho;
				Boyer_Moore bm_in;
				while (!myfile.eof()) {
					getline (myfile,file_string);

					// caso seja -e, --edit
					if(edit_flag) {
						bool ret = false;
						if(pattern_flag) {
							for (std::set<std::string>::iterator itP = patterns_set.begin(); itP != patterns_set.end(); ++itP) {
								if (color_flag) {
									std::vector<int> sell_ret = sellers(file_string, *itP, emax);
	
									if (sell_ret.size() > 0){
										printColorResultAho(sell_ret, file_string);
										break;
									}
								} else {
									if(sellers_bool(file_string, *itP, emax)) {
										printf("%s\n", file_string.c_str());
										break;
									}
								}
							}
						} else {
							if(color_flag){
								std::vector<int> sell_ret = sellers(file_string, patternStr, emax);
								if(sell_ret.size() > 0)
									printColorResultAho(sell_ret, file_string);
							} else {
								if(sellers_bool(file_string, patternStr, emax)) {
									printf("%s\n", file_string.c_str());
								}
							}
						}			
					}
					// caso seja -p, --patterns
					else if(pattern_flag) {
						if(fsmAho.g.size() == 0){
							fsmAho = returnFsmAho(patterns_set);
						}
						
						if(color_flag) {
							std::vector<int> aho_r = aho_c(file_string, fsmAho);
							
							if(aho_r.size() > 0) {
								printColorResultAho(aho_r, file_string);
							}
						} else {
							if(aho(file_string, fsmAho))
								printf("%s\n", file_string.c_str());	
						}
					}
					// caso nao seja --edit
					else {						
						if(!bm_in.isInitialized()) {
							bm_in.init(patternStr, patternStr.length());
						}
						
						if (color_flag) {
							std::vector<int> bm_r = bm_in.search_c(file_string, patternStr);
							if(bm_r.size() > 0) 
								printColorResult(bm_r, file_string, patternStr);
						} else {
							if(bm_in.search(file_string, patternStr)) {
								printf("%s\n", file_string.c_str());
							}
						}
					}
				}	
				myfile.close();
			} else {
				printf("Unable to open text file\n");
			}
		}
	} else { // opcao -h, --help foi escolhida
		showHelp();
	}
	
	exit (0);
}